考虑以下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
也是一样的?反之亦然(假设没有重复的元素)?
答案 0 :(得分:11)
LinkedHashSet
所做的保证是关于迭代顺序。但是,它仍然只是一个Set
而且一套并不关心订单本身。另一方面,List
确实如此。第{3}位元素List
与第1位元素相同的其他List
不同。
Set
javadoc
如果指定的对象也是一个集合,则返回true,这两个集合具有 相同的大小,和指定集的每个成员都包含在中 这个集合(或者等效地,这个集合的每个成员都包含在 指定的集合)。 此定义确保equals方法 在设置界面的不同实现中正常工作。
LinkedHashSet
javadoc状态
使用Set接口的哈希表和链表实现 可预测的迭代顺序。
LinkedHashSet
是Set
。它有相同的规则,即。适用于ADT的那些。
答案 1 :(得分:0)
如上所述: LinkedHashSet扩展了HashSet,它扩展了AbstractSet,它实现了equals方法:https://docs.oracle.com/javase/8/docs/api/java/util/AbstractSet.html#equals-java.lang.Object-
将指定对象与此集进行相等性比较。如果给定对象也是一个集合,则返回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