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:开 equals()
StringBuilderextends Object,这意味着它继承了Object.equals();但它不会覆盖equals(),这意味着StringBuilder.equals()实际上是Object.equals().
Object.equals()反过来基本上是==,即当且仅当两个对象是相同的内存地址时它才返回真。
Object.equals() java doc
注2:为什么?
仅从 JDK11 开始,StringBuilder实现Comparable. 任何伴随的变化都equals()可能导致一些旧的客户端代码被破坏;所以,我认为,遵循 Java 保持向后兼容的传统,他们放弃了这个想法。