簡體   English   中英

使用流刪除一個列表中的元素(如果存在於另一個列表中)

[英]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

如果在類Car中正確實現了hashCodeequals方法,則基於流的解決方案可能如下所示:

  • 過濾掉值,收集到一個新列表中
// 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);

如果您由於某種原因在類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
cars1.removeIf(c1 -> cars2
    .stream()
    .anyMatch(c2 -> c1.getId() == c2.getId() 
        && Objects.equals(c1.getName(), c2.getName())
    )
);

只需使用 removeAll() 方法即可完成。 您必須在 Car 類中實現 hashcode 和 equals。 然后你可以cars1.removeAll(cars2); . 這個語句只會在cars1 列表中留下c1。

推薦的解決方案是覆蓋類Car中的toStringhasCode()方法,然后您可以像問題下面已經評論的那樣,執行類似的操作

cars1.removeAll(cars2);

或者

cars1.removeIf(cars2::contains);

但是,如果這兩個方法在類Car中沒有被覆蓋,則必須比較嵌套循環中的每個屬性。 這種方法只對學習嵌套循環有用,從不推薦用於生產。

演示:

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

輸出:

[Car [id=1, name=C1]]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM