2017-02-27 10 views
4

以下の実装ではJava 8ストリームを使用します。基本的に私は1つのリストを解析し、別のオブジェクトの別のリストを形成したい。ネストされたループをJava 8ストリームに置き換える方法

入力 - 人物のPOJOのリスト、 出力 - PersonInfo用のPOJOのリスト

List<Person> persons = new ArrayList<Person>(); 

    Person max = new Person(); 
    max.setName("Max"); 
    max.setAge(10); 
    max.addAddress(new Address("Street1", "City1")); 
    max.addAddress(new Address("Street2", "City2")); 

    Person peter = new Person(); 
    peter.setName("Peter"); 
    peter.setAge(20); 
    peter.addAddress(new Address("Street1", "City1")); 
    peter.addAddress(new Address("Street2", "City2")); 

    persons.add(max); 
    persons.add(peter); 

    System.out.println("Input: " + persons); 

    List<PersonInfo> personInfos = new ArrayList<PersonInfo>(); 
    PersonInfo personInfo = null; 
    for (Person person : persons) { 
     for (Address addr : person.getCurrAndPrevAddrs()) { 
      personInfo = new PersonInfo(); 
      personInfo.setName(person.getName()); 
      personInfo.setAge(person.getAge()); 
      personInfo.setAddrs(addr);    
      personInfos.add(personInfo); 
     } 
    } 

    System.out.println("Output: " + personInfos.toString()); 

サンプル出力入力:[最大10 [Street1 CITY1、STREET2 City2この式]

、Peter 20 [Street1 City1、Street2 City2]

出力:最大10 Street1 CITY1

、最大10 STREET2 City2この式

、ピーター20 Street1 CITY1

、ピーター20 STREET2 City2この式]ここ

+0

出力:入力:?? –

+0

@Elise van Looij、私はサンプル出力を提供して、私の質問に_最後に入力しました。追加情報が必要な場合はお知らせください。 – Pons

答えて

4
List<PersonInfo> personInfos = persons.stream().flatMap(person -> person.getCurrAndPrevAddrs().stream().map(addr -> { 
     PersonInfo personInfo = new PersonInfo(); 
     personInfo.setName(person.getName()); 
     personInfo.setAge(person.getAge()); 
     personInfo.setAddrs(addr);    
     return personInfo; 
})).collect(Collectors.toList()); 
+0

コンパイルエラーが発生します。 1. 'persons.flatMap'、' persons 'はリストまたはストリームです。あなたは 'persons.stream()。flatMap'2と言うことを意味すると思います。型の不一致:ストリームからリストに変換できません。 – Pons

+1

@Pons I私の電話では、それは私が確認することは難しいです。あなたはもっと具体的になりますか? – shmosel

+1

@Ponsあなたは最初の点で正しいです。私はかっこも見逃しました。今すぐやってみて下さい。 – shmosel

2

を簡略化あなたがしようとしているもののバージョン。私はテストのためにPojosを単純化しました。

public class Person { 
    //getters, setters, etc. 
    public List<PersonInfo> toPersonInfos() { 
     List<PersonInfo> result = new ArrayList<>(); 
     for (Address addr : getCurrentAndPrevAddrs()) { 
      PersonInfo pi = new PersonInfo(); 
      pi.setName(this::getName); 
      pi.setAge(this::getAge); 
      pi.setAddrs(this::addr); 
      result.add(pi); 
     } 
     return result; 
    } 
} 

そのように、あなたがいる場合:(1)読みやすさを向上させ、(2)あなたのコードのメンテナンスを簡素化する

List<Person> persons = new ArrayList<Person>(); 

Person person1 = new Person("person1"); 
Person person2 = new Person("person2"); 

persons.add(person1); 
persons.add(person2); 

List<PersonInfo> personInfos = new ArrayList<PersonInfo>(); 
persons.stream().forEach(person -> {  
    person.getCurrAndPrevAddrs().stream().forEach(address -> { 
    PersonInfo personInfo = new PersonInfo("personInfo"); 
    personInfo.setAddress(address); 
    personInfos.add(personInfo); 
    }); 
}); 

System.out.println("Output: " + personInfos.toString()); 
+0

ありがとう、これは正常に動作しています。しかし、一つのことは、 'forEach'は' Iterable'で利用できるので、私は頭を抱えようとしていますが、これが私に与えるメリットは何ですか? – Pons

+0

これは並列実装で 'ConcurrentModificationException'を送出するようです。 – MikaelF

1

一つの方法はそうのように、あなたのPersonクラスにtoPersonInfoメソッドを追加することですPersonInfoまたはPersonクラスを変更するには、1つのメソッドを変更するだけで済みます。これは、Personクラスにあります。

それはまた大幅ストリーム操作が簡単になります。これは必ずしも順序付きリストを返しません

personInfos = persons.stream().flatMap(p -> p.toPersonInfos.stream()).collect(Collectors.toList()); 

注こと。

関連する問題