Java 8 流 - 通过比较两个列表进行过滤

Ami*_*mit 3 java java-8 java-stream

我有 2 个彼此不同的列表

public class App1{
    private String name;
    private String city;

    // getter setter

    // constructors
}

public class App2{
    private String differentName;
    private String differentCity;
    private String someProperty1;
    private String someProperty2;

    // getter setter

    // constructors
}

List<App1> app1List = new ArrayList<>();
app1List.add(new App1("test1","city1"));
app1List.add(new App1("test2","city2"));
app1List.add(new App1("test3","city3"));
app1List.add(new App1("test4","city4"));

List<App2> app2List = new ArrayList<>();
app2List.add(new App2("test2","city2"));
app2List.add(new App2("test3","city3"));
Run Code Online (Sandbox Code Playgroud)

如您所见,App1 和 App2 类是 2 个具有不同属性名称的不同 pojo,但是 name、city 和 differentName、 differentCity 属性分别持有的内容/值是相同的,即 test1、test2、test3 和 city1、city2 等

现在我需要过滤 app1List 比较其他列表中的名称和城市,即不存在的 app2List。

最终输出将是

app1List.add(new App1("test1","city1"));
app1List.add(new App1("test4","city4"));
Run Code Online (Sandbox Code Playgroud)

最简单的方法是多次循环其他列表之一,这是我试图避免的。Java 8 流中有什么方法不必循环多次?

Nam*_*man 6

您可以使用noneMatch操作,例如:

List<App1> result = app1List.stream()
        .filter(app1 -> app2List.stream()
                .noneMatch(app2 -> app2.getDifferentCity().equals(app1.getCity()) &&
                        app2.getDifferentName().equals(app1.getName())))
        .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

这假设两者的组合name并且在 ingcity时匹配filter。