#java #java-7
#java #набор деревьев
Вопрос:
Если бы я использовал Set
аналогичный этому:
Set<node> s=new TreeSet<node>();
class node {
private int x;
private int y;
}
Будет ли это приемлемо, и, поскольку это TreeSet, будет ли он также сортировать его?
Ответ №1:
Он не сможет отсортировать его без вашей реализации Comparable<Node>
, и он не будет действительно подходящим для операций set, пока вы не переопределите equals()
и hashCode()
. (Вам не нужно переопределять equals
и hashCode
для TreeSet
работы, но это имело бы смысл сделать.)
Что-то вроде этого:
final class Node implements Comparable<Node> {
private final int x;
private final int y;
Node(int x, int y) {
this.x = x;
this.y = y;
}
@Override public boolean equals(Object other) {
if (!(other instanceof Node)) {
return false;
}
Node otherNode = (Node) other;
return x == otherNode.x amp;amp; y == otherNode.y;
}
@Override public int hashCode() {
return x * 31 y * 17; // For example...
}
@Override public int compareTo(Node other) {
// As of Java 7, this can be replaced with
// return x != other.x ? Integer.compare(x, other.x)
// : Integer.compare(y, other.y);
if (x < other.x || (x == other.x amp;amp; y < other.y)) {
return -1;
}
return x == other.x amp;amp; y == other.y ? 0 : 1;
}
}
(Обратите внимание, что по соглашению имя класса будет Node
, а не node
.)
Комментарии:
1. в чем причина его создания
final class
?2. @medopal: равенство и другие вещи становится сложнее реализовать правильно (когда даже есть представление о правильности), когда задействовано наследование. Аналогично, когда я знаю, что подклассов нет, я знаю, что он неизменяем. В основном я подписываюсь на «дизайн для наследования или запрещаю его».
3. или «в зависимости от варианта использования» используйте guava или apache commons, чтобы избежать ветвления в вашем коде и позволить библиотеке реализовать метод hashcode и equals .
4. @Carlos: Нет, отсюда и предложение «Вам не нужно переопределять equals и hashCode для работы TreeSet, но это имело бы смысл сделать». Мне гораздо легче рассуждать о коде, когда сопоставимые реализации также подчиняются естественному равенству.
5. «Обратите внимание, что null не является экземпляром какого-либо класса, и e.compareTo(null) должен вызывать исключение NullPointerException, даже если e.equals(null) возвращает false». Удалите первый оператор if.
Ответ №2:
Узел должен реализовать сопоставимый, или вам нужно передать пользовательский компаратор, который может сравнивать два объекта узла. Кроме того, любая коллекция на основе хэша зависит от объекта, соответствующим образом переопределяющего equals() и hashcode() метод.
Комментарии:
1. К вашему сведению, TreeSet не основан на хэше.
2. @Bohemian да, вы правы, TreeSet или TreeMap специально не используют хеширование.
Ответ №3:
Вы должны указать equals, hashCode и реализовать сопоставимый интерфейс
Комментарии:
1. На самом деле это неверно. Достаточно просто сопоставимого. Вы должны реализовать equals() , но Object.equals() и Object.hashcode() по умолчанию достаточны для «работы» — в этом нет «необходимости».
Ответ №4:
В коде нет ничего плохого в том, что касается принятия as. Но для сортировки Node
класс ДОЛЖЕН реализовывать сопоставимый интерфейс.