Предположим, мне нужно 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()
, если мне не нужна стабильная сортировка?