如何从列表A中获取列表B中不存在的元素

时间:2019-07-24 13:42:40

标签: java lambda filter java-8 java-stream

我想从列表A中过滤列表B中不存在的所有对象。如何使用Java Stream做到这一点?

List<MyClass> A
List<MyClass> B

我想按MyClass.id字段进行过滤

我的尝试:

List<MyClass> actionsToRemoval = A.stream()
                .filter(oldAction -> B.stream()
                        .noneMatch(action -> action.getId() != null && action.getId().equals(oldAction.getId()))).collect(
                        Collectors.toList());

但是结果与我的预期相反

更新:

我来自DEV的代码:

来自数据库的数据:

private void removeUnnecessaryCorrectiveActions(List<IncidentCorrectiveActionDto> correctiveActionsDto) 
{
//correctiveActionsDto - data from Frontend, for exampe that object contains 3 objects with id=1 (this object should be updated), id=2 (new object), id=3 (ne w object)
List<IncidentCorrectiveAction> oldActions = incidentCorrectiveActionRepository
                .findByIncidentId(id)
//oldActions -> for example one object with id=1, fetched from database

    List<IncidentCorrectiveAction> actionsToRemoval = oldActions.stream()
                    .filter(oldAction -> correctiveActionsDto.stream()
                            .noneMatch(action -> action.getId() != null && action.getId().equals(oldAction.getId()))).collect(
                            Collectors.toList());

因此,在这种情况下,我想要添加2个新元素并将其保存在数据库中时,我的List actionsToRemoval应该返回0个元素。

另一种情况: oldActions-> 3个ID = 1,ID = 2,ID = 3的对象

correctiveActionsDto(前端对象)->包含1个ID = 1的对象

在这种情况下,actionsToRemoval List应该返回2个元素:id = 2和id = 3,因为这些对象应该从数据库中删除。

2 个答案:

答案 0 :(得分:1)

DATETIME

将列表List<MyClass> FilteredOutput = A.stream() .filter(e -> B.stream().map(MyClass::getid).anyMatch(id -> id.equals(e.getid()))) .collect(Collectors.toList()); 作为流,然后将A中的ID与A的ID进行比较。

答案 1 :(得分:1)

最好的方法是将谓词逻辑封装在对象的equals方法中,然后使用B.contains(x)作为过滤器。 像这样:

class MyClass{
   private Integer id;
   ...
   public boolean equals(Object other){
     return other instanceof MyClass && other.getId() != null && other.getId().equals(this.id);
} 

然后:

List<MyClass> A = ...;
List<MyClass> B = ...;

List<MyClass> diffAB = A.stream().filter(v -> !B.contains(v)).collect(Collectors.asList());