Компаратор и равно () - PullRequest
       53

Компаратор и равно ()

10 голосов
/ 03 декабря 2010

Предположим, мне нужно TreeSet с элементами, отсортированными по некоторой доменной логике. По этой логике не имеет значения порядок элементов, которые не равны, поэтому метод сравнения может вернуть 0, но в этом случае я не смог бы поместить их в TreeSet.

Итак, вопрос: какие недостатки я получу от такого кода:

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;
    }
});

Обновление

Ok. Если это всегда должно быть согласованность между методами equals(), hashcode() и compareTo(), как сказали @ S.P.Floyd - seanizer и другие. Будет ли лучше или даже хорошо, если я уберу Comparable интерфейс и перенесу эту логику в Comparator (я могу сделать это без нарушения инкапсуляции)? Так будет:

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;
    }
});

Обновление 2 :

Будет ли System.identityHashCode(x) лучше, чем hashCode(), если мне не нужна стабильная сортировка?

Ответы [ 11 ]

1 голос
/ 03 декабря 2010

Очень интересный вопрос. Насколько я понимаю, ваша проблема состоит в дублировании элементов.

Я думаю, что если o1.equals (o2), то их хэш-коды тоже могут быть равны. Это зависит от реализации hashCode () в вашем классе Foo. Итак, я бы предложил вам использовать System.identityHashCode (x) вместо этого.

...