检查一个列表是否包含另一个列表中的元素
我有两个列表,其中有不同的对象。检查一个列表是否包含另一个列表中的元素
List<Object1> list1;
List<Object2> list2;
我要检查,如果从列表1元素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;
}
但我认为这是一个更好更快的方式来做到这一点:) 有人能提出呢?
谢谢!
这可以通过基本的JDK来完成,无需在一个行修改输入列表
!Collections.disjoint(list1, list2);
这不会总是返回false,因为它们都是2个不同的对象? – Venki 2014-02-19 15:02:13
恩,不是吗?不相交的测试是否在两个集合之间没有对象equals()。 – 2014-02-19 16:15:56
此外,请注意,对于列表,这将是O(n * m);如果你愿意在比较之前把'list1'复制到'Set'中,你将得到O(n)+ O(m),即O(n + m),代价是一些额外的RAM;这是在速度或内存之间进行选择的问题。 – 2016-03-01 13:10:21
为了让它更快,您可以添加一个中断;这样,如果发现被设置为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;
}
如果你想在名单代替的地图,作为关键字attributeSame,你可以在一个地图检查值更快,如果有相应的在第二张地图中的价值还是没有。
根据的JavaDoc为.contains(Object obj)
:如果此列表包含指定的元素,
返回true。更多 正式返回true,当且仅当此列表包含至少一个 元素e使得(o == null?e == null:o.equals(e))。
所以,如果你重写你的.equals()
方法了给定的对象,你应该能够做到:if(list1.contains(object2))...
如果元素将是唯一的(即具有不同的属性),你可以重写.equals()
和.hashcode()
并将所有内容存储在HashSets
中。这将允许您在常量时间内检查是否包含另一个元素。
您可以使用Apache Commons CollectionUtils:
if(CollectionUtils.containsAny(list1,list2)) {
// do whatever you want
} else {
// do other thing
}
这假定你已经正确重载了equals功能为您的自定义对象。
更快的方式将需要额外的空间。
例如:
把所有项目都在一个列表到一个HashSet(你必须自己实现哈希函数使用object.getAttributeSame())
经过其他列表并检查是否有任何项目在HashSet中。
这样,每个对象被访问最多一次。并且HashSet足够快以检查或插入O(1)中的任何对象。
有一个方法Collection
命名retainAll
但有一些副作用你reference
只保留此列表中包含的 指定集合(可选操作)的元素。换句话说,从列表中删除 所有未包含在 指定集合中的元素。
如果此列表改变调用的结果
它像
boolean b = list1.retainAll(list2);
你可以定义你持有的数据类型?这是大数据吗?它是排序? 我认为您需要根据数据考虑不同的效率方法。
例如,如果您的数据很大并且未排序,您可以尝试通过索引一起迭代这两个列表,并将每个列表属性存储在另一个列表助手中。 然后您可以通过帮助程序列表中的当前属性进行交叉检查。
祝你好运
编辑:我不会推荐重载等于。它的危险和可能违背你的对象oop的含义。
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
我想如果你添加元素'A'到第二个列表listTwo.add(“A”);即使Collections.disjoint(listOne,listTwo);返回true。 – 2017-06-28 20:56:58
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
首先,当您设置found = true;然后简单地打破;或出来的循环 – Shubhansh 2012-08-03 13:10:42
http://*.com/questions/5187888/java-searching-within-a-list-of-objects。此外,为了迅速搜索尝试使用二进制搜索,并改变你的DS套件的情况... – Shubhansh 2012-08-03 13:13:14
他们是否共享除了对象共同的父母? – Woot4Moo 2012-08-03 13:16:59