我想在一个类上实现一个equals方法,其中实例的相等性来自包含列表的'弱'相等,i。即不需要列表元素的相同顺序,而java.util.List.equals(Object)
(您可以在下面看到它的javadoc)需要相同的顺序。
那么,对列表执行与顺序无关的相等检查的最佳方法是什么?
我想将列表包装到新列表中,对它们进行排序,然后在那里执行等号。
或另一种方法(会使这个问题过时):改为使用TreeSet,这样,元素的顺序在具有相同元素的集合中总是相同。
/**
* Compares the specified object with this list for equality. Returns
* <tt>true</tt> if and only if the specified object is also a list, both
* lists have the same size, and all corresponding pairs of elements in
* the two lists are <i>equal</i>. (Two elements <tt>e1</tt> and
* <tt>e2</tt> are <i>equal</i> if <tt>(e1==null ? e2==null :
* e1.equals(e2))</tt>.) In other words, two lists are defined to be
* equal if they contain the same elements in the same order. This
* definition ensures that the equals method works properly across
* different implementations of the <tt>List</tt> interface.
*
* @param o the object to be compared for equality with this list
* @return <tt>true</tt> if the specified object is equal to this list
*/
boolean equals(Object o);
我知道答案并关闭了标签。之后我读了关于在这种情况下该怎么做的meta post。但是由于我的问题是由SO缓存的,所以无论如何我都会发布它。也许某人将来会遇到同样的“问题”。如果没有人,我会发布答案。
答案 0 :(得分:3)
如果您对添加第三方库没有异议,可以使用Apache Commons-Lang中的CollectionUtils.isEqualCollection(java.util.Collection a, java.util.Collection b)
。它基本上比较了两个任意集合(也是列表),忽略了元素的顺序。
来自API文档:
如果给定的集合包含完全相同的结果,则返回true 具有完全相同基数的元素。也就是说,如果是的话 a中的e的基数等于b中的e的基数 a或b中的元素e。
答案 1 :(得分:2)
如果你正在使用Eclipse Collections,你可以将两个列表转换为包,只需在包之间使用等号()。 Bag.equals()
的合同是,如果每个元素的数量相同,则两个行李是相等的,但订单不会考虑因素。这也有性能优势。 toBag()
和Bag.equals()
均为O(n),因此此方法比排序列表更快。
Assert.assertEquals(
Lists.mutable.with(1, 2, 3, 1).toBag(),
Lists.mutable.with(3, 2, 1, 1).toBag());
注意:我是Eclipse Collections的提交者。
答案 2 :(得分:1)
我可以想到几种方法,包括迭代列表并使用list.contains
作为Sotirios在他的评论中提及。另一种方法是使用(new HashSet(list1)).equals(new HashSet(list2))
(但这两种解决方案都会丢弃重复的条目)。
另一种包括测试重复条目等效性的方法是使用Collections.sort()
制作两个列表的排序副本,然后使用.equals()
进行比较。有很多声音方法可以做到这一点,可能比我在这里提到的要多得多。
答案 3 :(得分:0)
因为已经有了一些答案。我要发布我的。
我终于使用了java.util.List.containsAll(Collection<?>)
。我绊倒这种方法是我不想发布问题的原因。
@jarnbjo没有意识到你还可以考虑基数的维度!
编辑
添加了......解决基数问题。
Collection<Object> a, b;
boolean equal = (a.size() == b.size()) && a.containsAll(b);
但这也可能失败。如果集合a具有项目x两次,集合b具有项目y两次。然后大小相同,containsAll()
产生true
。