为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

摇曳的蔷薇 2023-09-06 14:56:59
我有 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"));如您所见,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"));最简单的方法是多次循环其他列表之一,这是我试图避免的。Java 8 流中有什么方法不必循环多次?
查看完整描述

3 回答

?
慕婉清6462132

TA贡献1804条经验 获得超2个赞

您可以使用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());

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


查看完整回答
反对 回复 2023-09-06
?
跃然一笑

TA贡献1826条经验 获得超6个赞

您需要override equals在类中使用方法App2:


public class App2{

    private String differentName;

    private String differentCity;

    private String someProperty1;

    private String someProperty2;


    // getter setter


    // constructors


    @Override

    public boolean equals(Object obj) {

       App2 app2 = (App2) obj;

       return this.differentName.equals(app2.getDifferentName()) && this.differentCity.equals(app2.getDifferentCity());

    }

}

然后您可以像这样在 list1 上使用 Streams:


app1List = app1List.stream()

                .filter(a-> !app2List.contains(new App2(a.getName(),a.getCity())))

                .collect(Collectors.toList());

输出:


[App1{name='test1', city='city1'}, App1{name='test4', city='city4'}]


查看完整回答
反对 回复 2023-09-06
?
吃鸡游戏

TA贡献1829条经验 获得超7个赞

假设您想要匹配名称和城市,您可以创建一个将对象映射到key的函数,例如:


public static Integer key(String name, String differentCity) {

    return Objects.hash(name, differentCity);

}

然后使用该键创建一组键,以便使用noneMatch进行过滤,例如:


Set<Integer> sieve = app2List.stream()

        .map(app2 -> key(app2.differentName, app2.differentCity)).collect(Collectors.toSet());


List<App1> result = app1List.stream().filter(app1 -> sieve.stream()

        .noneMatch(i -> i.equals(key(app1.name, app1.city))))

        .collect(Collectors.toList());


System.out.println(result);

输出


[App1{name='test1', city='city1'}, App1{name='test4', city='city4'}]

这种方法的复杂性在于O(n + m)其中n和m是列表的长度。


查看完整回答
反对 回复 2023-09-06
  • 3 回答
  • 0 关注
  • 109 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信