Java HashSet is allowing dupes; problem with comparable?

孤者浪人 提交于 2019-12-05 02:28:01

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.

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.

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.

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

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).

Atul

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

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.

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!