如果使用流存在于另一个列表中,则删除一个列表的元素
Removing elements of one list if present in another list using stream
我在这里没有找到关于这个问题的任何线索。如果存在于另一个列表 (cars2) 中,我正在尝试使用 java 流删除一个列表 (cars1) 的元素(在我的例子中为 Cars)。
我尝试使用 removeIf,但后来感觉它更适合用于字符串列表等
Car c1 = new Car();
c1.id = 1;
c1.name = "C1";
Car c2 = new Car();
c2.id = 2;
c2.name = "C2";
List<Car> cars1 = new ArrayList<Car>();
cars1.add(c1);
cars1.add(c2);
List<Car> cars2 = new ArrayList<Car>();
cars2.add(c2);
// TODO : Remove all the cars from cars1 list that are in cars2 list using java streams
如果方法 hashCode
和 equals
在 class Car
中正确实现,基于流的解决方案可能如下所示:
- 筛选出值,收集到一个新列表中
// Predicate.not added in Java 11
List<Car> notJava11 = cars1.stream()
.filter(Predicate.not(cars2::contains))
.collect(Collectors.toList());
List<Car> notIn2 = cars1.stream()
.filter(car -> !cars2.contains(car))
.collect(Collectors.toList());
- 对
cars2
使用forEach
(影响cars1
):
cars2.forEach(cars1::remove);
// no need to call cars2.stream().forEach(cars1::remove);
此处第一个出现的 Car 实例在 cars1
中被删除
removeIf
应该也可以
cars1.removeIf(cars2::contains);
如果你因为某些原因 equals
/hashCode
没有在 class Car
中被覆盖,可以提供以下解决方案:
List<Car> notIn2 = cars1
.stream()
.filter(c1 -> cars2
.stream()
.noneMatch(c2 ->
c1.getId() == c2.getId()
&& Objects.equals(c1.getName(), c2.getName())
)
)
.collect(Collectors.toList());
removeIf
:
cars1.removeIf(c1 -> cars2
.stream()
.anyMatch(c2 -> c1.getId() == c2.getId()
&& Objects.equals(c1.getName(), c2.getName())
)
);
只需使用 removeAll() 方法即可完成。您必须在 Car class 中实现 hashcode 和 equals。
然后就可以cars1.removeAll(cars2);
了。此语句将仅在 cars1 列表中留下 c1。
我在这里没有找到关于这个问题的任何线索。如果存在于另一个列表 (cars2) 中,我正在尝试使用 java 流删除一个列表 (cars1) 的元素(在我的例子中为 Cars)。 我尝试使用 removeIf,但后来感觉它更适合用于字符串列表等
Car c1 = new Car();
c1.id = 1;
c1.name = "C1";
Car c2 = new Car();
c2.id = 2;
c2.name = "C2";
List<Car> cars1 = new ArrayList<Car>();
cars1.add(c1);
cars1.add(c2);
List<Car> cars2 = new ArrayList<Car>();
cars2.add(c2);
// TODO : Remove all the cars from cars1 list that are in cars2 list using java streams
如果方法 hashCode
和 equals
在 class Car
中正确实现,基于流的解决方案可能如下所示:
- 筛选出值,收集到一个新列表中
// Predicate.not added in Java 11
List<Car> notJava11 = cars1.stream()
.filter(Predicate.not(cars2::contains))
.collect(Collectors.toList());
List<Car> notIn2 = cars1.stream()
.filter(car -> !cars2.contains(car))
.collect(Collectors.toList());
- 对
cars2
使用forEach
(影响cars1
):
cars2.forEach(cars1::remove);
// no need to call cars2.stream().forEach(cars1::remove);
此处第一个出现的 Car 实例在 cars1
removeIf
应该也可以
cars1.removeIf(cars2::contains);
如果你因为某些原因 equals
/hashCode
没有在 class Car
中被覆盖,可以提供以下解决方案:
List<Car> notIn2 = cars1
.stream()
.filter(c1 -> cars2
.stream()
.noneMatch(c2 ->
c1.getId() == c2.getId()
&& Objects.equals(c1.getName(), c2.getName())
)
)
.collect(Collectors.toList());
removeIf
:
cars1.removeIf(c1 -> cars2
.stream()
.anyMatch(c2 -> c1.getId() == c2.getId()
&& Objects.equals(c1.getName(), c2.getName())
)
);
只需使用 removeAll() 方法即可完成。您必须在 Car class 中实现 hashcode 和 equals。
然后就可以cars1.removeAll(cars2);
了。此语句将仅在 cars1 列表中留下 c1。