我看不懂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
实现Comparable
。equals()
中任何伴随的变化都可能导致一些旧的客户端代码中断;所以,我想,遵循Java保持向后兼容的传统,他们放弃了这个想法。