2016-06-01 14 views
4

の交差点、私は2つのオブジェクトのリストを持っている:異なるオブジェクトタイプのJavaの2つのコレクション8

List<SampleClassOne> listOne; 
List<SampleClassTwo> listTwo; 

SampleClassOne:

public class SampleClassOne{ 
    private String myFirstProperty; 
    //ommiting getters-setters 
} 

SampleClassTwo:

public class SampleClassTwo{ 
    private String myOtherProperty; 
    //ommiting getters-setters 
} 

RootSampleClass:

public class RootSampleClass{ 
    private SampleClassOne classOne; 
    private SampleClassTwo classTwo; 
    //ommiting getters-setters 
} 

今、私は条件に基づいて型RootSampleClassの新しいリストに二つのリストをマージしたい:

if(classOneObject.getMyFirstProperty().equals(classTwoObject.getMyOtherProperty()){ 
//create new RootSampleClass based on classOneObject and classTwoObject and add it to another collection 
} 

擬似コード:

foreach(one: collectionOne){ 
foreach(two: collectionTwo){ 
    if(one.getMyFirstProperty().equals(two.getMyOtherProperty()){ 
    collectionThree.add(new RootSampleClass(one, two)); 
    } 
} 
} 

私がしたい私は、Java 8に興味ここで最高のパフォーマンスを発揮するので、カスタムforeachを書かずに既存のソリューションを求めています。ネストされたループに

+1

2つのリストをプロパティでソートした方が効率的でしょうか?あなたはそれに基づいて解決策を試み、あなたの質問にそのコードを追加するかもしれません。あなたが通常試したことを示す実際の例は、より良い答えをもたらします。 –

+2

2つの 'SampleClassOne'に同じ' myFirstProperty'があるとどうなりますか? – Tunaki

+0

それぞれのカスタムを望んでいないということはどういう意味ですか?あなたがやろうとしていることに対しては、あらかじめ箱に入れられた解決策はありません。 – cyroxis

答えて

7

直接等価は、m×n個の操作を行うための悪いパフォーマンスを含む直接等価、に重点を置いて

List<RootSampleClass> result = listOne.stream() 
    .flatMap(one -> listTwo.stream() 
     .filter(two -> one.getMyFirstProperty().equals(two.getMyOtherProperty())) 
     .map(two -> new RootSampleClass(one, two))) 
    .collect(Collectors.toList()); 

あります。

より良い解決策は、リストの1つを効率的な検索をサポートするデータ構造に変換することです。ハッシュマップこの対価は、使用しているAPIの質問とは関係ありません。あなたはストリームAPIを求めているので、あなたはこのようにそれを行うことができます。両方のソリューションは、ケース内のすべての可能なペアリングを作成します

Map<String,List<SampleClassOne>> tmp=listOne.stream() 
    .collect(Collectors.groupingBy(SampleClassOne::getMyFirstProperty)); 
List<RootSampleClass> result = listTwo.stream() 
    .flatMap(two -> tmp.getOrDefault(two.getMyOtherProperty(), Collections.emptyList()) 
     .stream().map(one -> new RootSampleClass(one, two))) 
    .collect(Collectors.toList()); 

注意を、プロパティ値は、いずれかまたは両方のリスト内で複数回発生します。あなたが潜在的に二重の検索を実行する気にしない場合は、以下より読みやすいコードで、最後のソリューションを置き換えることができ

Map<String, SampleClassOne> tmp=listOne.stream() 
    .collect(Collectors.toMap(SampleClassOne::getMyFirstProperty, Function.identity())); 
List<RootSampleClass> result = listTwo.stream() 
    .flatMap(two -> Optional.ofNullable(tmp.get(two.getMyOtherProperty())) 
      .map(one -> Stream.of(new RootSampleClass(one, two))).orElse(null)) 
    .collect(Collectors.toList()); 

:プロパティの値は、各リスト内で一意である場合は、IDのように、あなたは以下のソリューションを使用することができます:

Map<String, SampleClassOne> tmp=listOne.stream() 
    .collect(Collectors.toMap(SampleClassOne::getMyFirstProperty, Function.identity())); 
List<RootSampleClass> result = listTwo.stream() 
    .filter(two -> tmp.containsKey(two.getMyOtherProperty())) 
    .map(two -> new RootSampleClass(tmp.get(two.getMyOtherProperty()), two)) 
    .collect(Collectors.toList()); 
+0

非常に良い答え!大変ありがとう、これは私が探していたものです:) – Gazeciarz

関連する問題