Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't custom comparator be used with hashSet to check duplicate objects

I want to use a custom comparator to filter duplicate objects from a HashSet.

In the Mobile class, I have defined a non-static nested Comparator class for comparing. The criterium which is used by this comparator is the id field of the Mobile object.

Set<Mobile> treeSet = new TreeSet<>(new Mobile().new Comparator()); // works


Set<Mobile> hashSet = new HashSet<>(new Mobile().new Comparator()); // does not work

Even though it works perfectly for a TreeSet, Eclipse shows a syntax error when I try this with a HashSet,

It appears that I need to override the equals and hashcode methods in the Mobile class if I want to use a HashSet. However, I would prefer to use a comparator instead.

Why is this the case?

like image 889
rhozet Avatar asked Jan 26 '14 11:01

rhozet


2 Answers

Hashset is designed not to accept duplicates !. So if your set does not contain given element it will add it to the set. If however in your set such element appears 2nd (same) element will not be added and will be discarded.

HashSet:

class offers constant time performance for the basic operations (add, remove, contains and size). it does not guarantee that the order of
elements will remain constant over time iteration performance depends on the initial capacity and the load factor of the HashSet. It's
quite safe to accept default load factor but you may want to specify
an initial capacity that's about twice the size to which you expect
the set to grow.

TreeSet:

guarantees log(n) time cost for the basic operations (add, remove and contains) guarantees that elements of set will be sorted (ascending, natural, or the one specified by you via it's constructor) doesn't offer any tuning parameters for iteration performance offers a few handy methods to deal with the ordered set like first(), last(), headSet(), and tailSet() etc

Important points:

Both guarantee duplicate-free collection of elements It is generally faster to add elements to the HashSet and then convert the collection to a TreeSet for a duplicate-free sorted traversal. None of these implementation are synchronized. That is if multiple threads access a set concurrently, and at least one of the threads modifies the set, it must be synchronized externally. LinkedHashSet is in some sense intermediate between HashSet and TreeSet. Implemented as a hash table with a linked list running through it, however it provides insertion-ordered iteration which is not same as sorted traversal guaranteed by TreeSet.

like image 124
Maciej Cygan Avatar answered Oct 16 '22 05:10

Maciej Cygan


HashSet<Mobile> mobileSet = new HashSet(new Mobile().new Comparator())

Let's enumerate several things which are wrong with that line of code:

  • it is missing the ending semicolon (your "syntax error");
  • it is missing the generic type parameter (or diamond operator) on new HashSet;
  • it is using a constructor argument of incompatible type with HashSet(Collection<? extends E> coll).

The Javadoc of HashSet explains how a hash set works. It should be very easy to realize it has nothing to do with Comparators.

like image 31
Marko Topolnik Avatar answered Oct 16 '22 05:10

Marko Topolnik