[英]Removing elements of one list if present in another list using stream
I didn't find any thread here on this Question.我在此问题上没有找到任何线索。 I am trying to Remove elements (Cars in my case) of one list (cars1) if present in another list (cars2) using java stream.
如果存在于另一个列表 (cars2) 中,我正在尝试使用 java 流删除一个列表 (cars1) 的元素(在我的情况下为 Cars)。 I tried using removeIf but then it felt like it works more appropriately with List of Strings, etc.
我尝试使用 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
If methods hashCode
and equals
are properly implemented in class Car
, the stream-based solutions may look as follows:如果在类
Car
中正确实现了hashCode
和equals
方法,则基于流的解决方案可能如下所示:
// 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());
forEach
for cars2
(affecting cars1
):cars2
使用forEach
(影响cars1
):cars2.forEach(cars1::remove);
// no need to call cars2.stream().forEach(cars1::remove);
Here the first occurrence of Car instance is removed in cars1
这里第一次出现的 Car 实例在
cars1
被删除
removeIf
should work also removeIf
也应该工作cars1.removeIf(cars2::contains);
If you due to some reason equals
/ hashCode
are not overridden in class Car
, the following solution may be offered:如果您由于某种原因在类
Car
中没有覆盖equals
/ hashCode
,则可能会提供以下解决方案:
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
: removeIf
:cars1.removeIf(c1 -> cars2
.stream()
.anyMatch(c2 -> c1.getId() == c2.getId()
&& Objects.equals(c1.getName(), c2.getName())
)
);
It can be done simply by using removeAll() method.只需使用 removeAll() 方法即可完成。 You have to implement hashcode and equals in Car class.
您必须在 Car 类中实现 hashcode 和 equals。 Then you can
cars1.removeAll(cars2);
然后你可以
cars1.removeAll(cars2);
. . this statement would leave only c1 in cars1 list.
这个语句只会在cars1 列表中留下c1。
The recommended solution is to override toString
and hasCode()
methods in the class, Car
and then you can, as already comment below the question, do something like推荐的解决方案是覆盖类
Car
中的toString
和hasCode()
方法,然后您可以像问题下面已经评论的那样,执行类似的操作
cars1.removeAll(cars2);
or或者
cars1.removeIf(cars2::contains);
However, if these two methods are not overridden in the class, Car
, you will have to compare each attribute within the nested loops.但是,如果这两个方法在类
Car
中没有被覆盖,则必须比较嵌套循环中的每个属性。 This approach is only useful to learn nested loops and is never recommended for production use.这种方法只对学习嵌套循环有用,从不推荐用于生产。
Demo:演示:
import java.util.ArrayList;
import java.util.List;
class Car {
int id;
String name;
@Override
public String toString() {
return "Car [id=" + id + ", name=" + name + "]";
}
}
public class Main {
public static void main(String[] args) {
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);
for (int i = 0; i < cars1.size(); i++) {
Car car1 = cars1.get(i);
for (int j = 0; j < cars2.size(); j++) {
Car car2 = cars2.get(j);
if (car2.id == car1.id && car2.name.equals(car1.name))
cars1.remove(i);
}
}
System.out.println(cars1);
}
}
Output:输出:
[Car [id=1, name=C1]]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.