別のリストに基づいて 1 つのリストをストリーム フィルターする 質問する

別のリストに基づいて 1 つのリストをストリーム フィルターする 質問する

このフォーラムと Google で検索した後、質問を投稿しましたが、解決できませんでした。例:リンク1 リンク2 リンク3

リスト 1 の値に基づいてリスト 2 (複数列) をフィルタリングしようとしています。

List1:
 - [Datsun]
 - [Volvo]
 - [BMW]
 - [Mercedes]

List2: 
 - [1-Jun-1995, Audi, 25.3, 500.4, 300]
 - [7-Apr-1996, BMW, 35.3, 250.2, 500]
 - [3-May-1996, Porsche, 45.3, 750.8, 200]
 - [2-Nov-1998, Volvo, 75.3, 150.2, 100]
 - [7-Dec-1999, BMW, 95.3, 850.2, 900]

expected o/p:
 - [7-Apr-1996, BMW, 35.3, 250.2, 500]
 - [2-Nov-1998, Volvo, 75.3, 150.2, 100]
 - [7-Dec-1999, BMW, 95.3, 850.2, 900]

コード

// List 1 in above eg
List<dataCarName> listCarName = new ArrayList<>(); 
// List 2 in above eg
List<dataCar> listCar = new ArrayList<>(); 

// Values to the 2 lists are populated from excel

List<dataCar> listOutput = listCar.stream().filter(e -> e.getName().contains("BMW")).collect(Collectors.toList());

上記のコードでは、特定の値を指定するとフィルタリングできますが、リスト 2 の車名がリスト 1 に存在するかどうかを確認する方法がわかりません。

私が直面している問題が明確であることを願って、ガイダンスを待ちます (私はまだ Java に比較的慣れていないので、上記の質問が非常に基本的なものである場合はご容赦ください)。

編集上記のリンク 3 は解決するはずだと私は考えていますが、私のケースでは機能しません。おそらく、リスト 1 の値が org.gradle04.Main.Cars.dataCarName@4148db48 などとして入力されているためです。getName メソッドを呼び出してリスト 1 で forEach を実行する場合にのみ、人間が判読できる形式で値を取得できます。

ベストアンサー1

List<DataCarName>最初に ではなくが使用される理由が明確ではありませんList/Set<String>

提供する必要がある述語は、対応するデータ カー インスタンスについて、その名前がリスト内に存在するかどうかを確認する必要があります。

e -> e.getName().contains("BMW")は、データカーの名前にBMWが含まれているかどうかのみをチェックしますが、これは望ましくありません。最初の試みは、

e -> listCarName.contains(e.getName())

しかし、 は文字列 (だと思います) なので、listCarName結果として空のリストが返されます。List<DataCarName>e.getName()

最初のオプションは、述語を変更して、データ カー名のリストからストリームを取得し、それらを文字列表現にマップして、これらの名前のいずれかが現在フィルタリングしている現在のデータ カー インスタンスの名前に対応しているかどうかを確認することです。

List<DataCar> listOutput =
    listCar.stream()
           .filter(e -> listCarName.stream().map(DataCarName::getName).anyMatch(name -> name.equals(e.getName())))
           .collect(Collectors.toList());

これは、データ カー ストリーム パイプラインの各インスタンスに対してストリームを作成するため、非常にコストがかかります。より良い方法は、Set<String>車の名前を事前に指定した を作成し、containsこのセットの述語として を使用することです。

Set<String> carNames = 
    listCarName.stream()
               .map(DataCarName::getName)
               .collect(Collectors.toSet());

List<DataCar> listOutput =
     listCar.stream()
            .filter(e -> carNames.contains(e.getName()))
            .collect(Collectors.toList());

おすすめ記事