Alex Rivera | Logout

Comparator and equals()

Asked 2010-12-03T09:44:28.587
11

Suppose I need TreeSet with elements sorted with some domain logic. By this logic it doesn't matter order of some elements that doesn't equal so compare method can return 0, but in this case I couldn't put them in TreeSet.

So, question: what disadvantages I'll have from code like this:

class Foo implements Comparable<Foo>{}
new TreeSet<Foo>(new Comparator<Foo>(){
    @Override
    public int compare(Foo o1, Foo o2) {
        int res = o1.compareTo(o2);
        if(res == 0 || !o1.equals(o2)){
            return o1.hashCode() - o2.hashCode();
        }
        return res;
    }
});

Update:

Ok. If it should always be a consistency between the methods equals(), hashcode() and compareTo(), as @S.P.Floyd - seanizer and others said. If it would be better or even good if I'll remove Comparable interface and move this logic in Comparator (I can do it without broken encapsulation)? So it will be:

class Foo{}
new TreeSet<Foo>(new Comparator<Foo>(){
    @Override
    public int compare(Foo o1, Foo o2) {
        //some logic start
        if(strictliBigger(o1, o2)){ return 1;}
        if(strictliBigger(o2, o1)){ return -1;}
        //some logic end
        if(res == 0 || !o1.equals(o2)){
            return o1.hashCode() - o2.hashCode();
        }
        return res;
    }
});

Update 2:

Would System.identityHashCode(x) be better than hashCode() if I don't need stable sort?

Edit
Report

1 Answer

2

Beware: even for two Foos f1,f2 with f1 != f2 you could get f1.hashCode() == f2.hashCode()! That means you won't get a stable sorting with your compare Method.

answered 2010-12-03T09:58:32.083

Your Answer