Gru*_*eck 232 java collections
在标准Java库中,查找两个列表是否包含完全相同的元素的最简单方法是什么?
如果两个列表是相同的实例,则无关紧要,如果列表的类型参数不同则无关紧要.
例如
List list1
List<String> list2;
// ... construct etc
list1.add("A");
list2.add("A");
// the function, given these two lists, should return true
Run Code Online (Sandbox Code Playgroud)
我知道可能有些东西盯着我:-)
编辑:为了澄清,我正在按顺序寻找完全相同的元素和元素数量.
编辑:谢谢你指出我看不见的明显答案:-)
虽然到目前为止给出的所有答案都是正确的,但有些答案比其他答案更正确,所以在接受之前我会等待一段时间以获得最好的四舍五入的答案.
Lau*_*ves 339
如果您关心订单,那么只需使用equals方法:
list1.equals(list2)
Run Code Online (Sandbox Code Playgroud)
来自javadoc:
将指定对象与此列表进行比较以获得相等性.当且仅当指定的对象也是列表时,返回true,两个列表具有相同的大小,并且两个列表中的所有对应元素对都相等.(如果(e1 == null?e2 == null:e1.equals(e2)),则两个元素e1和e2相等.)换句话说,如果两个列表包含相同顺序的相同元素,则它们被定义为相等.此定义确保equals方法在List接口的不同实现中正常工作.
如果要独立于顺序进行检查,可以将所有元素复制到集合,并在结果集合上使用等于:
public static <T> boolean listEqualsIgnoreOrder(List<T> list1, List<T> list2) {
return new HashSet<>(list1).equals(new HashSet<>(list2));
}
Run Code Online (Sandbox Code Playgroud)
这种方法的局限在于它不仅忽略了顺序,而且忽略了重复元素的频率.例如,如果list1是["A","B","A"]并且list2是["A","B","B"],则该Set方法将认为它们是相等的.
如果您需要对顺序不敏感但对重复频率敏感,您可以:
Tom*_*Tom 89
我在评论中发布了一些内容,我认为它保证了自己的答案.
正如大家在这里所说,使用equals()取决于顺序.如果您不关心订单,您有3个选择.
选项1
使用containsAll().在我看来,这个选项并不理想,因为它提供了最差的性能,O(n ^ 2).
选项2
这有两种变化:
2a)如果你不关心维护你的列表的顺序...... Collections.sort()在两个列表上使用.然后使用equals().这是O(nlogn),因为你做了两种排序,然后是O(n)比较.
2b)如果您需要维护列表的顺序,可以先复制两个列表.然后,您可以在复制的列表上使用解决方案2a.然而,如果复制非常昂贵,这可能没有吸引力.
这导致:
选项3
如果您的要求与第2b部分相同,但复制过于昂贵.您可以使用TreeSet为您进行排序.将每个列表转储到自己的TreeSet中.它将在集合中排序,原始列表将保持不变.然后equals()对两个TreeSets 进行比较.所述TreeSetss时,可以建在O(nlogn)时间,并且equals()为O(n).
请你选择:-).
编辑:我几乎忘记了 Laurence Gonsalves指出的同一个警告.TreeSet实现将消除重复.如果您关心重复项,则需要某种排序的多重集.
meg*_*lop 19
如果您正在使用(或者很乐意使用)Apache Commons Collections,您可以使用CollectionUtils.isEqualCollection,如果给定的Collections包含具有完全相同基数的完全相同的元素,则返回true.
Rei*_*eus 12
聚会很晚但想要添加这个空的安全检查:
Objects.equals(list1, list2)
Run Code Online (Sandbox Code Playgroud)
小智 8
我知道这是一个旧线程,但其他答案都没有完全解决我的用例(我猜Guava Multiset也可以这样做,但这里没有例子).请原谅我的格式.我仍然很想在堆栈交换上发帖.另外,如果有任何错误,请告诉我
假设您有List<T>a和List<T>b,并且您想检查它们是否与以下条件相同:
1)O(n)的预计运行时间
2)相等,便定义为:对于a或b的所有元素时,发生的次数的元件在a等于b中发生元件的次数.元素相等定义为T.equals()
private boolean listsAreEquivelent(List<? extends Object> a, List<? extends Object> b) {
if(a==null) {
if(b==null) {
//Here 2 null lists are equivelent. You may want to change this.
return true;
} else {
return false;
}
}
if(b==null) {
return false;
}
Map<Object, Integer> tempMap = new HashMap<>();
for(Object element : a) {
Integer currentCount = tempMap.get(element);
if(currentCount == null) {
tempMap.put(element, 1);
} else {
tempMap.put(element, currentCount+1);
}
}
for(Object element : b) {
Integer currentCount = tempMap.get(element);
if(currentCount == null) {
return false;
} else {
tempMap.put(element, currentCount-1);
}
}
for(Integer count : tempMap.values()) {
if(count != 0) {
return false;
}
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
运行时间为O(n),因为我们正在将O(2*n)插入到散列映射中,并且O(3*n)散列映射选择.我还没有完全测试这段代码,所以要小心:)
//Returns true:
listsAreEquivelent(Arrays.asList("A","A","B"),Arrays.asList("B","A","A"));
listsAreEquivelent(null,null);
//Returns false:
listsAreEquivelent(Arrays.asList("A","A","B"),Arrays.asList("B","A","B"));
listsAreEquivelent(Arrays.asList("A","A","B"),Arrays.asList("A","B"));
listsAreEquivelent(Arrays.asList("A","A","B"),null);
Run Code Online (Sandbox Code Playgroud)
List 上的 equals 方法可以做到这一点,列表是有序的,因此要相等,两个列表必须具有相同顺序的相同元素。
return list1.equals(list2);
Run Code Online (Sandbox Code Playgroud)
private boolean listHaveEqualObjects(List<?> list1, List<?> list2){
return list1.containsAll(list2) && list2.containsAll(list1);
Run Code Online (Sandbox Code Playgroud)
尝试使用此版本,该版本不需要顺序相同,但支持具有多个相同值。仅当每个具有相同数量的任何值时,它们才匹配。
public boolean arraysMatch(List<String> elements1, List<String> elements2) {
// Optional quick test since size must match
if (elements1.size() != elements2.size()) {
return false;
}
List<String> work = newArrayList(elements2);
for (String element : elements1) {
if (!work.remove(element)) {
return false;
}
}
return work.isEmpty();
}
Run Code Online (Sandbox Code Playgroud)