我想迭代两个列表并获得新的过滤列表,其中的值将不会出现在第二个列表中。有人可以帮忙吗?
我有两个列表 - 一个是字符串列表,另一个是MyClass
个对象列表。
List<String> list1;
List<MyClass> list2;
MyClass {
MyClass(String val)
{
this.str = val;
}
String str;
...
...
}
我希望基于 - &gt;过滤掉字符串列表检查list1
中不存在其值的元素(abc)的第二个列表。
List<String> list1 = Arrays.asList("abc", "xyz", "lmn");
List<MyClass> list2 = new ArrayList<MyClass>();
MyClass obj = new MyClass("abc");
list2.add(obj);
obj = new MyClass("xyz");
list2.add(obj);
现在我想要新的过滤列表 - &gt;它将具有值=&gt; “LMN”。即list2
中不存在的元素,其元素位于list1
。
答案 0 :(得分:16)
// produce the filter set by streaming the items from list 2
// assume list2 has elements of type MyClass where getStr gets the
// string that might appear in list1
Set<String> unavailableItems = list2.stream()
.map(MyClass::getStr)
.collect(Collectors.toSet());
// stream the list and use the set to filter it
List<String> unavailable = list1.stream()
.filter(e -> unavailableItems.contains(e))
.collect(Collectors.toList());
答案 1 :(得分:6)
使用流进行操作非常简单易读:
Predicate<String> notIn2 = s -> ! list2.stream().anyMatch(mc -> s.equals(mc.str));
List<String> list3 = list1.stream().filter(notIn2).collect(Collectors.toList());
答案 2 :(得分:5)
最后,我得到了以下方式实现这一目标 -
List<String> unavailable = list1.stream()
.filter(e -> (list2.stream()
.filter(d -> d.getStr().equals(e))
.count())<1)
.collect(Collectors.toList());
但这也符合预期。 请告诉我这有效吗?如果有人有其他办法做同样的事情?
答案 3 :(得分:3)
如果您流式传输第一个列表并使用基于第二个包含的过滤器...
list1.stream()
.filter(item -> !list2.contains(item))
接下来的问题是,您将在此流媒体操作结束时添加哪些代码,以便将结果进一步处理给您。
另外,list.contains非常慢,所以使用sets会更好。
但是如果你正在使用集合,你可能会发现一些更简单的操作来处理这个问题,比如removeAll
Set list1 = ...;
Set list2 = ...;
Set target = new Set();
target.addAll(list1);
target.removeAll(list2);
鉴于我们不知道您将如何使用此功能,因此无法确定采用哪种方法。
答案 4 :(得分:2)
见下文,欢迎任何人对以下代码的反馈。
两个数组之间不常见:
List<String> l3 =list1.stream().filter(x -> !list2.contains(x)).collect(Collectors.toList());
两个数组之间的共同点:
List<String> l3 =list1.stream().filter(x -> list2.contains(x)).collect(Collectors.toList());
答案 5 :(得分:1)
list1 = list1.stream().filter(str1->
list2.stream().map(x->x.getStr()).collect(Collectors.toSet())
.contains(str1)).collect(Collectors.toList());
这可能会更有效。
答案 6 :(得分:0)
如果您的班级具有ID,并且您要按ID进行过滤
第1行:您映射了所有ID
第2行:过滤地图中不存在的内容
Set<String> mapId = entityResponse.getEntities().stream().map(Entity::getId).collect(Collectors.toSet());
List<String> entityNotExist = entityValues.stream().filter(n -> !mapId.contains(n.getId())).map(DTOEntity::getId).collect(Collectors.toList());
答案 7 :(得分:0)
@DSchmdit答案对我有用。我想补充一点。因此,我的要求是根据表中存储的某些配置来过滤文件。 首先检索文件并将其收集为dto列表。我从数据库接收配置,并将其存储为另一个列表。这就是我如何对流进行过滤
{{1}}
详细信息在过滤谓词的实现中。事实证明,与遍历循环和过滤相比,性能更强
答案 8 :(得分:0)
`List<String> unavailable = list1.stream()
.filter(e -> (list2.stream()
.filter(d -> d.getStr().equals(e))
.count())<1)
.collect(Collectors.toList());`
for this if i change to
`List<String> unavailable = list1.stream()
.filter(e -> (list2.stream()
.filter(d -> d.getStr().equals(e))
.count())>0)
.collect(Collectors.toList());`
will it give me list1 matched with list2 right?