0

TreeSet implements Set inteface, and thus prevents duplicate insertion. I used to think that when a new item is added to a set, its hashcode is computed, and afterwards the new item is being compared, using Object.equals(), to every other existing item, which might has the same hashcode as the new item. If a match is found, the new item will not be added eventually.

However, according to this, the following code is suppose to produce the output 3. That's because two Point variables are considered 'equal' if and only if they refer to the same address in the memory. While running this code shows that the actual output is 2, which means equality of two object is defined by compareTo instead of equals.

Can you explain this behavior?

public class Point implements Comparable<Point> {
    private int x;
    private int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public int compareTo(Point other) {
        return Integer.compare(other.y, this.y);
    }

    @Override
    public boolean equals(Object other) {
        return this == other;
    }

    public static void main(String[] args){
        Set<Point> mySet = new TreeSet<>();
        mySet.add(new Point(1,2));
        mySet.add(new Point(2,2));
        mySet.add(new Point(3,1));
        System.out.println(mySet.size());
    }
}

Edit: According to TreeSet documentation:

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

Ido
  • 397
  • 2
  • 7
  • 22
  • 1
    Did you read the documentation? Because I did and the information is right there. – Michael Sep 13 '19 at 12:17
  • I did, but probably not thoroughly enough. Thanks. I'll edit my post. – Ido Sep 13 '19 at 12:24
  • Then the relevant line is here: "*a [`TreeSet`](https://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html) 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`*" – Michael Sep 13 '19 at 12:25
  • [`Comparable`](https://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html) states that "*It is strongly recommended (though not required) that natural orderings be consistent with `equals`*", which your implementation does not follow – Michael Sep 13 '19 at 12:26
  • The `TreeSet` documentation which you quote precisely agrees with your conclusion that "equality of two object is defined by `compareTo`" (your words). Then what is the problem? – Michael Sep 13 '19 at 12:28
  • I stumbled by this code, which is deliberately flawed. I did not write it by myself and I know natural ordering should generally be consistent with equals. The problem was solved. – Ido Sep 16 '19 at 11:50

0 Answers0