2016-04-13 7 views
5

私はJava 8ストリームを扱っています。この問題を幻想的な方法で解決できるかどうかは疑問です。ストリームとフラットマップでオブジェクトを渡す

それは私のシナリオです: パーティーのリストがあり、各要素の中にメンバーの名前があるとします。私はリストを繰り返し、名前と所属するパーティーで新しいものを作りたいと思います。

私の最初のアプローチはした私の第二のアプローチで

@Test 
public void test(){ 

    Party firstParties = new Party("firstParty",Lists.newArrayList("Member 1","Member 2","Member 3")); 
    Party secondParty = new Party("secondParty",Lists.newArrayList("Member 4","Member 5","Member 6")); 

    List<Party> listOfParties = Lists.newArrayList(); 
    listOfParties.add(firstParty); 
    listOfParties.add(secondParty); 

    List<Elector> electors = new ArrayList<>(); 
    listOfParties.stream().forEach(party -> 
     party.getMembers().forEach(memberName -> 
      electors.add(new Elector(memberName,party.name)) 
     ) 
    ); 

} 

class Party { 
    List<String> members = Lists.newArrayList(); 
    String name = ""; 

    public Party(String name, List<String> members) { 
     this.members = members; 
     this.name = name; 
    } 

    public List<String> getMembers() { 
     return members; 
    } 
} 

class Elector{ 

    public Elector(String electorName,String partyName) { 

    } 

} 

私が使用しようとしたflatmapの操作をマップ:

@Test 
public void test(){ 

    Party firstParty = new Party("firstParty",Lists.newArrayList("Member 1","Member 2","Member 3")); 
    Party secondParty = new Party("secondParty",Lists.newArrayList("Member 4","Member 5","Member 6")); 

    List<Party> listOfParties = Lists.newArrayList(); 
    listOfParties.add(firstParty); 
    listOfParties.add(secondParty); 

    List<Elector> people = listOfParties.stream().map(party -> party.getMembers()) 
      .flatMap(members -> members.stream()) 
      .map(membersName -> new Elector(membersName, party.name)) #Here is my problem variable map doesn't exist 
      .collect(Collectors.toList()); 

} 

問題は、私は内部のパーティーのオブジェクトにアクセスすることはできませんです地図操作。 もう一度質問します。私はより機能的なやり方で対応できますか? (2番目のアプローチのように)

ありがとう!

+0

はい、ハックはメンバーとそのパーティを含むタプルのストリームにフラット・マップすることです。 '.flatMap(party - > party.getMembers()。stream()。map(メンバー - >新しいタプル<>(パーティー、メンバー))'のようなものです。タプルクラスが組み込まれていないので、あなた自身または(ab) 'AbstractMap.SimpleEntry'を使用してください... – Tunaki

+0

既に依存関係がある場合は、' Pair.of(party、member) 'をcommons-langから取得してください。 –

+2

@Tunaki:あなたは複雑すぎると思っています... – Holger

答えて

5

あなたは、個々の操作にあまり分解:

List<Elector> people = listOfParties.stream() 
    .flatMap(party -> party.getMembers().stream() 
     .map(membersName -> new Elector(membersName, party.name))) 
    .collect(Collectors.toList()); 

は、これが唯一の二番目は、今戻っ「サブ」に適用されて、生き残るflatMapステップ、に両方mapの手順を移動することで動作します。あなたの質問のコメントに指摘されているように、 "サブストリーム"要素をマップするには、ある種類のPairタイプが必要ですが、あなたのElectorタイプは、興味のある2つの値を使用して構築されているので、後でElectorにマップするために汎用Pair(member,party)にマップする必要はありません。私はStream<Elector>を取得するためにPartyクラス(またはどこか他の静的メソッド)にヘルパーメソッドを追加します読めるすべてのものを維持するために

2

public Stream<Elector> electors() { 
    return getMembers().stream().map(member -> new Elector(member, name)); 
} 
// Alternatively 
public static Stream<Elector> electors(final Party p) { 
    return p.getMembers().stream().map(member -> new Elector(member, p.name)); 
} 

そしてちょうどあなたのflatmapにそれを使用

final List<Elector> people = listOfParties.stream() 
    .flatMap(Party::electors) 
    .collect(Collectors.toList());