Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java8流-通过比较两个列表进行筛选_Java_Java 8_Java Stream - Fatal编程技术网

Java8流-通过比较两个列表进行筛选

Java8流-通过比较两个列表进行筛选,java,java-8,java-stream,Java,Java 8,Java Stream,我有两个不同的列表 public class App1{ private String name; private String city; // getter setter // constructors } public class App2{ private String differentName; private String differentCity; private String someProperty1;

我有两个不同的列表

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"));

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

您需要
重写
App2
类中的
equals
方法:

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());
    }
}
然后您可以在列表1中使用流,如下所示:

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'}]
您需要
重写
App2
类中的
equals
方法:

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());
    }
}
然后您可以在列表1中使用流,如下所示:

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'}]
您可以使用
非匹配操作,例如:

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

这假设
筛选时匹配
名称
城市
的组合。

您可以使用
非匹配
操作,例如:

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

这假设
筛选时匹配
名称
城市
的组合。

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

public static Integer key(String name, String differentCity) {
    return Objects.hash(name, differentCity);
}
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);
然后使用该键创建一组键,以便使用该键进行过滤,例如:

public static Integer key(String name, String differentCity) {
    return Objects.hash(name, differentCity);
}
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);

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

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

public static Integer key(String name, String differentCity) {
    return Objects.hash(name, differentCity);
}
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);
然后使用该键创建一组键,以便使用该键进行过滤,例如:

public static Integer key(String name, String differentCity) {
    return Objects.hash(name, differentCity);
}
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);

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

首先将一个列表转换为哈希集。如果您有一个输入
app2List.add(new App2(“test1”,“city4”);
也可以将一个列表转换为哈希集。如果您有一个输入
app2List.add(new App2)(“测试一,"城市四";也是吗?