【问题标题】:Why can equals not be inferred in HashSets where the type is specified?为什么在指定类型的HashSets中不能推断equals?
【发布时间】:2013-03-18 21:00:15
【问题描述】:

我不懂 Java 中的一些愚蠢的东西,希望你能帮我弄清楚。

我已经定义了Hashset<Point> myHashSet = new HashSet<Point>();

然后,我创建两个相等的 Point 点,Point p1 and Point p2,并将它们放在不同的变量/内存位置。然后我覆盖public boolean equals(Point other) 的.equals() 方法,并将我的第一个点p1 添加到HashSet。

然后我打电话给System.out.println(myHashSet.contains(p2)); // prints false

为什么编译器不能从创建时推断“哦,这个哈希集的类型是 Point”,并说“我应该检查 Point 是否覆盖了默认的 equals 方法......是的,我们称之为一个!”。

相反,我相信它调用对象的通用 equals 方法,因此我相信比较内存位置?

这样做的原因仅仅是 HashSet 可以包含 Point 的子类,它使用不同的 Equals 方法吗?这是我能看到当前行为的唯一原因,尽管我确信我忽略了一些东西:)。非常感谢。

【问题讨论】:

  • 你也覆盖了 hashCode 吗?
  • @EvanKnowles 我知道这也必须这样做,我更多的是问为什么 Java 不能从我创建的 HashSet 推断“这个 HashSet 只包含 Point 类型的对象,所以我应该'不要使用 Object equals 方法,我应该使用 Point one" :)
  • 啊 - 正如彼得所说,我相信您没有正确覆盖 equals 方法。你已经重载了它。

标签: java object collections hash equals


【解决方案1】:

集合使用您必须覆盖的Object.equals(Object)。如果您创建另一个方法,例如 equals(Point),它不会调用它。

相反,我相信它会调用对象的通用 equals 方法,从而比较内存位置,我相信?

是的,HashSet 可以通用调用的唯一方法是equals(Object)

这样做的原因仅仅是因为 HashSet 可以包含 Point 的子类,它使用不同的 Equals 方法吗?

HashSet 无法知道您想在运行时使用此方法。

【讨论】:

  • @Override 注释 equals 方法将是捕捉这种情况的好方法。
  • 是的,您已经重载了该方法。
  • 我知道这一点,我在问题中提到了这一点。我的问题是……为什么它不能从集合定义中的 推断出它应该为 Points 调用 equals 方法! :) 这不是更有意义吗? (我知道我忽略了一些东西,我只是想不通)。 :) 非常感谢您的回复。
  • a) 它在运行时无权访问该类 b) 如果您有接口,则无法在接口上定义 equals 方法。 c)这不适用于子类。 d) 如果它可以访问类并使用反射来调用它,它会慢得多。 e) 它与一般覆盖的工作方式不一致。
  • 泛型是一个编译时特性。所有 HashSet 的代码完全相同,每个 HashSet 都将调用相同的方法,即 equals(Object) ,但事实并非如此。
【解决方案2】:

您应该根据此文档http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#hashCode%28%29 重写 equals() 和 hashCode(),因为 HashSet 使用这两种方法来检查对象是否相等

【讨论】:

    【解决方案3】:

    您的问题在于public boolean equals(Point other),因为这不是Object 类中定义的默认equals 方法。

    如果您希望 HashMap 使用您的实现,则必须覆盖 public boolean equals(Object other)(注意 Object 而不是 Point)。请参阅 the documentation for Object 并注意,如果您覆盖 equals,您还应该覆盖 hashCode() 方法。

    【讨论】:

      【解决方案4】:

      尝试添加@Override 注释。您一定拼错了 equals 方法及其签名。

          @Override
          public boolean equals(Object obj) {
              // TODO Auto-generated method stub
              return super.equals(obj);
          }                
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-15
        • 1970-01-01
        相关资源
        最近更新 更多