StringBuilder实现了Comparable,但不覆盖equals



我看不懂javadoc中的这一行(在副标题"API注释"下):

StringBuilder实现了Comparable,但不覆盖equals。因此,StringBuilder的自然顺序与equals不一致。

我是Java的初学者,所以你能以一种简单的方式解释这个吗?

这意味着StringBuilder.compareTo()StringBuilder.equals()并不总是一致的。

var sb1 = new StringBuilder("foo");
var sb2 = new StringBuilder("foo");
assert sb1.compareTo(sb2) == 0;      // as you would expect.
assert sb1.equals(sb2) == true;      // surprise - it fails

现在它变得更令人困惑了:

var map = new HashMap<StringBuilder, String>();
map.put(sb1, "lorem ipsum");
assert map.size() == 1;
map.put(sb2, "dolor sit amet");
assert map.size() == 1;            // fails - it's 2
var set = new TreeSet<StringBuilder>();
set.add(sb1);
assert set.size() == 1;
set.add(sb2);
assert set.size() == 2;           // you'd think this should be 2 but it fails! 

这是因为HashMap适用于equals(),而SortedSet适用于compareTo()


注1:onequals()

StringBuilder扩展Object,这意味着它继承了Object.equals();但它不覆盖equals(),这意味着StringBuilder.equals()实际上是Object.equals()

Object.equals()反过来基本上是==,即当且仅当两个对象是相同的内存地址时,它返回true。

Object.equals() java doc


注2:为什么?

仅从JDK11开始,StringBuilder实现Comparableequals()中任何伴随的变化都可能导致一些旧的客户端代码中断;所以,我想,遵循Java保持向后兼容的传统,他们放弃了这个想法。

最新更新