当前位置: 首页 > 知识库问答 >
问题:

StringBuilder实现可比较但不覆盖相等

贝浩歌
2023-03-14

我不理解javadoc中的这一行(在“API注释”子标题下):

StringBuilder实现可比较但不覆盖等于。因此,StringBuilder的自然顺序与equals不一致。

我是Java的初学者,你能简单地解释一下吗?

共有1个答案

左丘宜年
2023-03-14

这意味着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()一起工作,而SortedSetcompareTo()一起工作。

注1:onequals()

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

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

object.equals()java doc

注2:为什么?

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

 类似资料:
  • 问题内容: 为什么StringBuffer的/ StringBuilder的没有覆盖,从对象的方法? 请给我建议清晰的图片,以帮助理解问题… 问题答案: 因为是可变的,所以它的主要用途是 构造 字符串。如果要比较内容,请调用并比较返回的值。 覆盖可变对象通常没有用,因为修改用作a键的对象可能会导致存储的值“丢失”。

  • 我知道这些接口用于对集合中的对象进行排序。但我怀疑这两者的真正区别。我读到的一个事实是,如果要比较两个对象而不使用当前对象,请使用Compariable(此)。 但我的问题是即使使用比较器,我们也会比较相同的对象类型。 这里真正的区别是什么。我很困惑。假设下面的例子, 如果我使用比较器,我会让一个类实现比较器,而不是这个。年龄,它有人。年龄那么这里有什么不同呢? 我不知道Collections.s

  • 使用Powershell 5,您现在可以实现自定义类。最终,您需要开始重载运算符以执行以下操作 但这似乎没有很好的记录,在Stack Overflow上搜索后,我找不到如何做到这一点。

  • 我在理解和使用比较器方面有一个问题,有人问我以下问题: 我在一个单独的Employee类中使用compareTo比较器接口来调用比较器对象的重载使用。 任何帮助,建议,代码行将非常感谢!!

  • 问题内容: 我知道python函数默认是虚拟的。假设我有这个: 我不希望他们能够这样做: 有没有办法防止用户重载roo()? 问题答案: 您可以使用元类: 每当创建子类时,就会调用该元类型的 new 。如果您在场,这将导致错误。仅当没有基类时,它才会接受roo的定义。 您可以通过使用注释来声明哪些方法是最终方法,从而使该方法更加理想。然后,您需要检查所有基准并计算所有最终方法,以查看是否有任何基准

  • 我在这里发布了一些代码,正确地解决了海报上的一个问题。OP希望删除重复项,并将某些特殊项置于列表的顶部。我使用了一个和一个特殊的类,该类包装了他们正在使用的,以实现他们想要的。 然后我开始想。。。正如你所做的。。。我是通过从方法返回来消除重复,而不是通过从实现返回来消除重复,这是正确指示中的重复(根据的定义)所需要的。 我不反对使用这种技术,但我是否使用了可能被视为未记录的功能?我是否可以放心地认