StringBuilder 实现 Comparable 但不覆盖 equals

StringBuilder implements Comparable but does not override equals

我不明白line from javadoc(在副标题“API 注释”下):

StringBuilder implements Comparable but does not override equals. Thus, the natural ordering of StringBuilder is inconsistent with 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:在 equals()

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

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

Object.equals() java doc


注2:为什么?

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