检查一个列表是否包含另一个列表中的元素

时间:2012-08-03 13:08:26

标签: java list find element

我有两个包含不同对象的列表。

List<Object1> list1;
List<Object2> list2;

我想检查list1中的元素是否存在于list2中,基于特定属性(Object1和Object2具有(等等),一个相互属性(类型为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;
}

但我认为有更好更快的方法来做到这一点:) 有人可以提出来吗?

谢谢!

12 个答案:

答案 0 :(得分:196)

这可以使用基本JDK完成,而无需修改一行中的输入列表

!Collections.disjoint(list1, list2);

答案 1 :(得分:33)

您可以使用Apache Commons CollectionUtils

if(CollectionUtils.containsAny(list1,list2)) {  
    // do whatever you want
} else { 
    // do other thing 
}  

这假设您已正确重载自定义对象的equals功能。

答案 2 :(得分:9)

Collection名为retainAll一种方法,但对您有{strong>副作用 <{3}}

  

仅保留此列表中包含的元素   指定集合(可选操作)。换句话说,删除   从这个列表中的所有元素都没有包含在   指定的集合。

     

如果此列表因调用而改变,则为

就像

boolean b = list1.retainAll(list2);

答案 3 :(得分:5)

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

答案 4 :(得分:2)

根据.contains(Object obj)的JavaDoc:

  

如果此列表包含指定的元素,则返回true。更多   正式地,当且仅当此列表包含至少一个时才返回true   元素e使得(o == null?e == null:o.equals(e))。

因此,如果您覆盖给定对象的.equals()方法,则应该可以:if(list1.contains(object2))...

如果元素是唯一的(即具有不同的属性),您可以覆盖.equals().hashcode()并将所有内容存储在HashSets中。这将允许您检查是否在恒定时间内包含另一个元素。

答案 5 :(得分:2)

更快的方式将需要额外的空间。

例如:

  1. 将所有项目放在一个列表中(您必须自己实现哈希函数才能使用object.getAttributeSame())

  2. 浏览另一个列表,检查HashSet中是否有任何项目。

  3. 这样每个对象最多访问一次。和HashSet足够快,可以检查或插入O(1)中的任何对象。

答案 6 :(得分:1)

为了让它更快,你可以添加休息时间;这样,如果found设置为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;
}

如果你有地图而不是带有按键属性列表的列表,如果第二张地图中有相应的值,你可以更快地检查一张地图中的值。

答案 7 :(得分:1)

要缩短Narendra的逻辑,可以使用以下方法:

boolean var = lis1.stream().anyMatch(element -> list2.contains(element));

答案 8 :(得分:0)

您可以定义您持有的数据类型吗?这是大数据吗?它排序了吗? 我认为您需要根据数据考虑不同的效率方法。

例如,如果您的数据很大且未排序,您可以尝试通过索引将两个列表一起迭代,并将每个列表属性存储在另一个列表助手中。 然后你可以通过助手列表中的当前属性进行交叉检查。

祝你好运

编辑:我不建议重载equals。它的危险性可能与你的目标有关。或者

答案 9 :(得分:0)

org.springframework.util.CollectionUtils

boolean containsAny(java.util.Collection<?> source, java.util.Collection<?> candidates)

Return true if any element in 'candidates' is contained in 'source'; otherwise returns false

答案 10 :(得分:0)

使用 java 8 ,我们可以像下面一样检查一个列表是否包含其他列表的任何元素

boolean var = lis1.stream().filter(element -> list2.contains(element)).findFirst().isPresent();

答案 11 :(得分:0)

如果要检查列表中是否存在元素,请使用contains方法。

if (list1.contains(Object o))
{
   //do this
}