检查一个列表是否包含另一个列表中的元素
我有两个不同的对象在他们的列表。
List<Object1> list1; List<Object2> list2;
我想检查list1中是否存在list1中的元素,基于特定的属性(Object1和Object2有(除其他外),一个互相属性(types为Long),名为attributeSame)。
现在,我这样做:
boolean found = false; for(Object1 object1 : list1){ for(Object2 object2: list2){ if(object1.getAttributeSame() == object2.getAttributeSame()){ found = true; //also do something } } if(!found){ //do something } found = false; }
但我认为有一个更好,更快的方式来做到这一点:)有人可以提出呢?
谢谢!
这可以通过基本的JDK来完成,而无需修改一行中的input列表
!Collections.disjoint(list1, list2);
您可以使用Apache Commons CollectionUtils :
if(CollectionUtils.containsAny(list1,list2)) { // do whatever you want } else { // do other thing }
这假定您已经正确地重载了自定义对象的equalsfunction。
有一个 Collection
方法名为retainAll
但有一些副作用供您参考
仅保留指定集合中包含的此列表中的元素(可选操作)。 换句话说,从这个列表中删除所有不包含在指定集合中的元素。
如果此列表因呼叫而改变,则为true
就像是
boolean b = list1.retainAll(list2);
更快的方式将需要额外的空间。
例如:
-
把所有项目放在一个HashSet中(你必须自己实现hash函数来使用object.getAttributeSame())
-
浏览另一个列表并检查是否有任何项目在HashSet中。
这样每个对象最多访问一次。 并且HashSet足够快以检查或插入O(1)中的任何对象。
根据JavaDoc的.contains(Object obj)
:
如果此列表包含指定的元素,则返回true。 更正式地说,当且仅当这个列表包含至less一个元素e,使得(o == null?e == null:o.equals(e))返回true。
所以如果你重写你的.equals()
方法给你的对象,你应该能够做到: if(list1.contains(object2))...
如果元素是唯一的(即具有不同的属性),则可以覆盖.equals()
和.hashcode()
并将所有内容存储在HashSets
。 这将允许您检查是否包含另一个元素在恒定的时间。
Loius答案是正确的,我只是想添加一个例子:
listOne.add("A"); listOne.add("B"); listOne.add("C"); listTwo.add("D"); listTwo.add("E"); listTwo.add("F"); boolean noElementsInCommon = Collections.disjoint(listOne, listTwo); // true
为了让它更快,你可以添加一个rest; 这样循环将停止,如果find设置为true:
boolean found = false; for(Object1 object1 : list1){ for(Object2 object2: list2){ if(object1.getAttributeSame() == object2.getAttributeSame()){ found = true; //also do something break; } } if(!found){ //do something } found = false; }
如果您将地图replace为属性同名关键字的列表,那么如果第二张地图中存在相应的值,则可以更快地检查一张地图中的值。
你可以定义你所持有的数据types吗? 这是大数据吗? 它是sorting? 我认为您需要根据数据考虑不同的效率方法。
例如,如果您的数据很大并且未sorting,您可以尝试通过索引一起迭代这两个列表,并将每个列表属性存储在另一个列表助手中。 那么您可以通过帮助程序列表中的当前属性进行交叉检查。
祝你好运
编辑:我不会推荐重载等于。 它的危险性可能是违背你的对象的意思。