Java HashSet 允许欺骗;问题有可比性吗?

发布于 2024-09-03 18:56:57 字数 243 浏览 2 评论 0原文

我有一个类“Accumulator”,它实现了 Comparable CompareTo 方法,并且我试图将这些对象放入 HashSet 中。

当我将 add() 添加到 HashSet 时,无论我在何处设置断点,我在调试器中的compareTo 方法中都看不到任何活动。此外,当我完成 add() 后,我在 Set 中看到了几个重复项。

我在这里搞砸了什么;为什么它不进行比较,从而允许欺骗?

谢谢,
IVR复仇者

I've got a class, "Accumulator", that implements the Comparable compareTo method, and I'm trying to put these objects into a HashSet.

When I add() to the HashSet, I don't see any activity in my compareTo method in the debugger, regardless of where I set my breakpoints. Additionally, when I'm done with the add()s, I see several duplicates within the Set.

What am I screwing up, here; why is it not Comparing, and therefore, allowing the dupes?

Thanks,
IVR Avenger

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

溇涏 2024-09-10 18:56:57

我在这里搞砸了什么?

HashSet 基于 hashCode(),而不是 compareTo()。您可能会将它与 TreeSet 混淆。在这两种情况下,请确保以与其他方法一致的方式实现 equals() 。

What am I screwing up, here?

HashSet is based on hashCode(), not on compareTo(). You may be confusing it with TreeSet. In both cases, be sure to also implement equals() in a manner that is consistent with the other method.

秋凉 2024-09-10 18:56:57

您需要正确实现 hashCode()equals()

您必须重写 hashCode 并根据类中的值返回一个数字,以便任何两个相等的对象具有相同的哈希码。

You need to correctly implement hashCode() and equals().

You must override hashCode and return a number based on the values in your class such that any two equal objects have the same hashcode.

情场扛把子 2024-09-10 18:56:57

HashSet 使用 hashCode()equals() 方法来防止添加重复项。首先,它获取要添加的对象的哈希码。然后,它找到该哈希码对应的存储桶,并使用 equals() 方法迭代该存储桶中的每个对象,以查看存储桶中是否已存在任何相同的对象。放。

您的调试器不会在 compareTo() 上中断,因为它从未与 HashSet 一起使用!

规则是:

  1. 如果两个对象相等,则它们的哈希码
    必须相等。

  2. 但是如果两个对象的哈希码
    相等,那么这意味着
    对象是平等的!可能是
    这两个对象恰好具有相同的哈希值。

HashSet uses the hashCode() and equals() methods to prevent duplicates from being added. First, it gets the hash code of the object you want to add. Then, it finds the corresponding bucket for that hash code and iterates through each object in that bucket, using the equals() method to see if any identical objects already exist in the set.

Your debugger is not breaking on compareTo() because it is never used with HashSet!

The rules are:

  1. If two objects are equal, then their hash codes
    must be equal.

  2. But if two objects' hash codes
    are equal, then this doesn't mean
    the objects are equal! It could be
    that the two objects just happen to have the same hash.

爺獨霸怡葒院 2024-09-10 18:56:57

当 hashCode 对 2 个对象返回不同的值时,则不使用 equal。顺便说一句,compareTo 与散列集合无关:) 但与排序集合无关

When hashCode return different values for 2 objects, then equal is not used. Btw, compareTo has nothing to do with hashing collections :) but sorted collections

冰雪梦之恋 2024-09-10 18:56:57

您的对象是Comparable,并且可能您也实现了equals(),但是HashSets处理对象哈希,并且很可能您还没有实现。 t 实现的 hashCode() (或者您的 hashCode() 实现不会为 (a.equals(b) = = true)

Your objects are Comparable, and probably you've implemented equals() too, but HashSets deal with object hashes, and odds are you haven't implemented hashCode() (or your implementation of hashCode() doesn't return the same hash for two objects that are (a.equals(b) == true).

执手闯天涯 2024-09-10 18:56:57

人们往往忽视一件事,从而导致巨大的错误。
在定义 equals 方法时,始终将参数作为对象类,然后将对象转换为所需的类。
例如,

   public bolean equals(Object aSong){
     if(!(aSoneg instanceof Song)){
       return false;
     }
     Song s=(Song) aSong;
     return getTitle().equals(s.getTitle());
   }

如果您通过写 Song aSong 而不是 Object aSong 您的 equals 方法将永远不会被调用。

希望这有帮助

One thing which people tends to ignore which result in a huge mistake.
While defining equals method always take the parameter as object class and then conver the object to your desired class.
For eg

   public bolean equals(Object aSong){
     if(!(aSoneg instanceof Song)){
       return false;
     }
     Song s=(Song) aSong;
     return getTitle().equals(s.getTitle());
   }

If u pass write Song aSong instead of Object aSong your equals method will never get called.

Hope this helps

探春 2024-09-10 18:56:57

HashSet 使用 hashCode 和 equals。 TreeSet 使用 Comparable 接口。注意:如果您决定覆盖 hashcode 或 equals,则应始终覆盖另一个。

HashSet uses hashCode and equals. TreeSet uses the Comparable interface. Note: if you decide to override either hashcode or equals, you should always override the other.

眼泪也成诗 2024-09-10 18:56:57

当您创建 Accumulator 类的对象时,它会在 JVM 中占用新空间,并在每次您在 中添加对象时返回唯一的 hashCode哈希集。它不依赖于对象的值,因为您没有重写 hashCode() 方法,因此它将调用 ObjecthashCode() 方法这将为程序中创建的每个对象返回唯一的 hashCode。

解决方案:

重写 hashCode()equals() 方法,并根据类的属性应用您的逻辑。请务必阅读 equals 和 hashcode 约定

http://www.ibm.com/developerworks/ java/library/j-jtp05273/index.html

When ever you create an object of class Accumulator it takes new space in JVM and returns unique hashCode every time you add an object in hashSet. It does not depends upon the value of the object because you have not overridden hashCode() method hence it will call Object class hashCode() method which will return unique hashCode with every object created in your program.

Solution:

Override hashCode() and equals() method and apply your logic depending upon the properties of your class. Be sure to read equals and hashcode contract

http://www.ibm.com/developerworks/java/library/j-jtp05273/index.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文