LinkedHashSet .equals() против LinkedList .equals() с теми же элементами, но в другом порядке
Рассмотрим следующий SSCCE:
public static void main(String[] args) {
LinkedHashSet<String> set1 = new LinkedHashSet<>();
set1.add("Bob");
set1.add("Tom");
set1.add("Sam");
LinkedHashSet<String> set2 = new LinkedHashSet<>();
set2.add("Sam");
set2.add("Bob");
set2.add("Tom");
System.out.println(set1);
System.out.println(set2);
System.out.println(set1.equals(set2));
}
Это печатает:
[Bob, Tom, Sam]
[Sam, Bob, Tom]
true
Тем не менее, если вы измените LinkedHashSet
в LinkedList
:
public static void main(String[] args) {
LinkedList<String> set1 = new LinkedList<>();
set1.add("Bob");
set1.add("Tom");
set1.add("Sam");
LinkedList<String> set2 = new LinkedList<>();
set2.add("Sam");
set2.add("Bob");
set2.add("Tom");
System.out.println(set1);
System.out.println(set2);
System.out.println(set1.equals(set2));
}
он производит:
[Bob, Tom, Sam]
[Sam, Bob, Tom]
false
У меня вопрос прояснения. Может ли кто-нибудь помочь разобраться в этом? Почему бы LinkedHashSet
считаться равными, тогда как то же самое LinkedList
не будет? Я предполагаю определение List
а также Set
играет роль, но я не уверен.
По сути, я говорю, если вы считаете, Set
то же самое, не могли бы вы рассмотреть List
Неужели тоже самое? И наоборот (при условии отсутствия дублирующих элементов)?
2 ответа
Гарантия того, что LinkedHashSet
делает о порядке итерации. Тем не менее, это все еще Set
и набор не заботится о порядке сам по себе. List
с другой стороны, делает. List
с элементом в 3-й позиции не совпадает с другим List
с тем же элементом в 1-й позиции.
Set
Javadoc для equals(Object)
метод
Возвращает true, если указанный объект также является набором, два набора имеют одинаковый размер, и каждый член указанного набора содержится в этом наборе (или, что то же самое, каждый член этого набора содержится в указанном наборе). Это определение гарантирует, что метод equals работает должным образом в разных реализациях интерфейса set.
LinkedHashSet
Javadoc заявляет
Реализация хеш-таблицы и связанного списка интерфейса Set с предсказуемым порядком итераций.
LinkedHashSet
это Set
, У него те же правила, т.е. те, которые применяются к установленному ADT.
Как упоминалось выше: LinkedHashSet расширяет HashSet, который расширяет AbstractSet, который реализует метод equals: https://docs.oracle.com/javase/8/docs/api/java/util/AbstractSet.html
Сравнивает указанный объект с этим набором на равенство. Возвращает true, если данный объект также является набором, два набора имеют одинаковый размер, и каждый член данного набора содержится в этом наборе. Это гарантирует, что метод equals работает должным образом в разных реализациях интерфейса Set.
Самый простой способ сравнить LinkedHashSet, если он важен для вас, - это его сериализовать и сравнить:
LinkedHashSet<Integer> reverseOrder = new LinkedHashSet<>();
reverseOrder.add(2);
reverseOrder.add(1);
LinkedHashSet<Integer> ordered = new LinkedHashSet<>();
ordered.add(1);
ordered.add(2);
System.out.println("Equals via set: " + ordered.equals(reverseOrder));
System.out.println("Equals With Arrays: " + ordered.ordered.toString().equals(reverseOrder.ordered.toString()));
Результат:
Equals via Set: true
Equals With Arrays: false