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)(“测试一,"城市四";代码>也是吗?