如何检查两个ArrayLists是否彼此不同?我不在乎有什么区别,我只是想知道它们是不是一样。
我每分钟从数据库中获取分数列表,并且只有当我获取的分数列表与我在一分钟前获取的分数列表不同时,我才想将其发送给客户端。
现在,ArrayList的值实际上是我创建的一个类(包含name,lvl,rank,score)。
我是否需要在其上实施equals()
?
答案 0 :(得分:79)
正如约阿希姆所指出的,对于大多数应用,List.equals(Object o)
定义有效:
将指定对象与此列表进行比较以获得相等性。当且仅当指定的对象也是列表时,返回
true
,两个列表具有相同的大小,并且两个列表中的所有对应元素对都相等。 (如果e1
,则两个元素e2
和(e1==null ? e2==null : e1.equals(e2))
相等。)换句话说,如果两个列表包含相同顺序的相同元素,则它们被定义为相等。此定义确保equals
方法在List
接口的不同实现中正常工作。
根据您使用它的方式,这可能无法按预期工作。例如,如果你有一个List<int[]>
,它就不能正常工作,因为数组从equals
继承了Object
,它将相等性定义为引用标识。
List<int[]> list1 = Arrays.asList(new int[] { 1, 2, 3 });
List<int[]> list2 = Arrays.asList(new int[] { 1, 2, 3 });
System.out.println(list1.equals(list2)); // prints "false"
此外,具有不同类型参数的两个列表可以是equals
:
List<Number> list1 = new ArrayList<Number>();
List<String> list2 = new ArrayList<String>();
System.out.println(list1.equals(list2)); // prints "true"
您还提到该列表必须包含具有相同类型的元素。这是另一个示例,其中元素的类型不同,但它们是equals
:
List<Object> list1 = new ArrayList<Object>();
List<Object> list2 = new ArrayList<Object>();
list1.add(new ArrayList<Integer>());
list2.add(new LinkedList<String>());
System.out.println(list1.equals(list2)); // prints "true"
因此,除非您明确定义平等对您意味着什么,否则问题的答案可能会有很大差异。但是,对于大多数实际目的,List.equals
应该足够了。
equals
更新后的信息表明List.equals
可以正常完成工作,提供元素正确实现equals
(因为List<E>.equals
调用E.equals
根据上面的API文档,在非null
- 元素上。
因此,在这种情况下,如果我们有List<Player>
,那么Player
必须@Override equals(Object o)
才能true
o instanceof Player
以及相关的equals
字段,它们都是==
(对于引用类型)或@Override equals
(对于基元)。
当然,当您@Override int hashCode()
时,您还应该return 42;
。几乎不可接受的最小值是return name.hashCode();
; equals
;稍微好一点;最好是使用涉及您定义equals/hashCode
的所有字段的公式。一个好的IDE可以自动生成equals/hashCode
方法。
Object.equals(Object)
Object.hashCode()
java.lang.Comparable
- 此处不需要,但另一个重要的Java API合同在equals
组合:
在==
vs {{1}}上:
答案 1 :(得分:11)
使用equals()
。只要列表中的元素正确实现equals()
,它就会返回正确的值。
除非您想忽略值的顺序,否则您应该将值转储到两个Set
对象中,并使用equals()
进行比较。
答案 2 :(得分:8)
这是一个简单的方法,可以检查2个数组列表是否包含相同的值,无论它们的顺序如何。
//the name of the method explains it well...
public boolean isTwoArrayListsWithSameValues(ArrayList<Object> list1, ArrayList<Object> list2)
{
//null checking
if(list1==null && list2==null)
return true;
if((list1 == null && list2 != null) || (list1 != null && list2 == null))
return false;
if(list1.size()!=list2.size())
return false;
for(Object itemList1: list1)
{
if(!list2.contains(itemList1))
return false;
}
return true;
}
答案 3 :(得分:2)
正如@Joachim Sauer在他的回答中提到的,如果列表相同且其内容实现正确,则equals应该有效。但是,如果项目不在同一个“订单”中,它不应该工作,因为它不使用包含检查。从这个意义上说,它检查@jarnbjo
提到的“严格”平等 //From android's Arraylist implementation
Iterator<?> it = that.iterator();
for (int i = 0; i < s; i++) {
Object eThis = a[i];
Object eThat = it.next();
if (eThis == null ? eThat != null : !eThis.equals(eThat)) {
return false;
}
}
然而,我想要一些不同的行为,我不关心秩序或类似的东西。我想要的只是确保两个不包含相同的项目。 我的解决方案,
//first check that both are not null and are of same length. (not shown here)
//if both match, pull out the big guns as below
...
List<Object> comparedList = new ArrayList<>(listOne);
comparedList.removeAll(listTwo);
if(comparedList.size() != 0) //there are differences between the two
性能较差,因为它循环两次,先是removeAll
,然后是contains
,removeAll
调用。
我的名单保证很短,所以我不介意打击。
答案 4 :(得分:2)
您可以将它们转换为字符串,然后比较
list1.toString().equals(list2.toString())
答案 5 :(得分:-1)
您还可以查看Arraylist,如下所示:
public boolean equalLists(List<String> one, List<String> two){
if (one == null && two == null){
return true;
}
if((one == null && two != null)
|| one != null && two == null
|| one.size() != two.size()){
return false;
}
//to avoid messing the order of the lists we will use a copy
//as noted in comments by A. R. S.
one = new ArrayList<String>(one);
two = new ArrayList<String>(two);
Collections.sort(one);
Collections.sort(two);
return one.equals(two);
}
感谢@Jacob