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
Другие вопросы по тегам