LinkedHashSet .equals()vs LinkedList .equals()具有相同的元素但顺序不同

考虑以下SSCCE:

public static void main(String[] args) { LinkedHashSet set1 = new LinkedHashSet(); set1.add("Bob"); set1.add("Tom"); set1.add("Sam"); LinkedHashSet 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 set1 = new LinkedList(); set1.add("Bob"); set1.add("Tom"); set1.add("Sam"); LinkedList 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不会? 我假设ListSet的定义起作用,但我不确定。

基本上,我是说如果你认为Set是相同的,你会不会认为List也是一样的? 反之亦然(假设没有重复的元素)?

LinkedHashSet的保证是关于迭代顺序。 但是,它仍然是一个Set而一个集合本身并不关心顺序。 另一方面, List确实如此。 具有第3位元素的List与第1位置具有相同元素的其他List不同。

equals(Object)方法Set javadoc

如果指定的对象也是一个集合,则返回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#equals-java.lang.Object-

将指定对象与此set进行相等性比较。 如果给定对象也是一个集合,则返回true,两个集合具有相同的大小,并且给定集合的每个成员都包含在此集合中。 这可确保equals方法在Set接口的不同实现中正常工作。

比较LinkedHashSet的最简单方法,如果对您来说重要的顺序是序列化并比较它们:

  LinkedHashSet reverseOrder = new LinkedHashSet<>(); reverseOrder.add(2); reverseOrder.add(1); LinkedHashSet 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