3

I want to have some pairs of int in a TreeSet, and sort them by the first number.

Code test here:

public static void main (String[] args) throws java.lang.Exception
{
    SortedSet<int[]> s = new TreeSet<int[]>(new Comparator<int[]>(){
        public int compare(int[] a, int[] b) {
            return b[0] - a[0];
        }
    });
    int[] a = new int[]{1, 2};
    int[] b = new int[]{1, 3};
    s.add(a);
    s.add(b);
    System.out.println(s.size());
}

I don't know why the size of TreeSet turns out to be 1. Seems like the hashCode of a and b are same, but why?

Thanks for any help.

BTW: in fact, I was trying to put duplicate numbers in a set, which is not possible. Then I tried to have int pairs in a set. The first number is the actual number I want, the second number was there to prevent duplication. But I run into this problem.

Kumar Abhinav
  • 6,565
  • 2
  • 24
  • 35
Meng Wang
  • 277
  • 1
  • 8

2 Answers2

5

It turns out to be 1 because your compare method only uses the first number in the array, and the two arrays you have both begin with 1. Therefore, from the point of view of the TreeSet, the two arrays are the same.

TreeSet.add returns

true if this set did not already contain the specified element

, and since the two values are considered equal (compare returns 0), the second value is not added and add() returns false

Paul Boddington
  • 37,127
  • 10
  • 65
  • 116
  • Might want to point out that [TreeSet.add()](http://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html#add%28E%29) returns "true if this set did not already contain the specified element", and since the two values are considered equals (`compare` returns 0), the second value is *not* added and `add()` returns `false`. – Andreas Oct 10 '15 at 21:36
  • @Andreas Good thinking. Will you object if I just cut and paste your exact words? – Paul Boddington Oct 10 '15 at 21:37
  • *For complete answer:* Definition of a `Set` is "[a collection that contains no duplicate elements](http://docs.oracle.com/javase/7/docs/api/java/util/Set.html)". If you don't want duplicates eliminated, don't use a `Set`. You'd want a sorted "Bag", which in Java means a `PriorityQueue`. – Andreas Oct 10 '15 at 21:45
  • Thanks! Now I know that TreeSet uses `compare` method instead of `hashCode()` to tell the equality of elements. And also thanks for the suggestion of `PriorityQueue`. Appreciate your help. – Meng Wang Oct 10 '15 at 21:49
  • @MengWang Not all `Set`s. `HashSet` uses `hashCode()` and `equals()`.You need to carefully read the documentation of any class before you use it. – Paul Boddington Oct 10 '15 at 21:50
3

It's a common mistake to think that hashcode plays a role in Tree based data structure,it actually doesn't.Hash Based collections(HashSet,LinkedHashSet,HashMap,LinkedHashMap and few others ) use hashing along with equals to differentiate an Object.

In your case,a TreeSet,you are treating object equality using a comparator which considers equality based on length of array sizes.If two arrays have same size,it considers equal.So in your case,the array b replaces array a in the head node as both arrays have length 1.Even if you override hashcode,it won't be of any use.

From JavaDocs:-

Note that the ordering maintained by a set (whether or not an explicit comparator is provided) must be consistent with equals if it is to correctly implement the Set interface. (See Comparable or Comparator for a precise definition of consistent with equals.) This is so because the Set interface is defined in terms of the equals operation, but a TreeSet instance performs all element comparisons using its compareTo (or compare) method, so two elements that are deemed equal by this method are, from the standpoint of the set, equal. The behavior of a set is well-defined even if its ordering is inconsistent with equals; it just fails to obey the general contract of the Set interface.

Kumar Abhinav
  • 6,565
  • 2
  • 24
  • 35
  • Thanks! Now I know that Set/Map use `compare()` instead of `hashCode()` to tell equality of elements/keys. Appreciate your help. – Meng Wang Oct 10 '15 at 21:48