2015-10-26 13 views
9

私は以下のクラスを持っています。カスタムコレクタを使用したJava 8のグループ化?

class Person { 

    String name; 
    LocalDate birthday; 
    Sex gender; 
    String emailAddress; 

    public int getAge() { 
     return birthday.until(IsoChronology.INSTANCE.dateNow()).getYears(); 
    } 

    public String getName() { 
     return name; 
    } 
} 
私は年齢によってグループにできるようにして、人物の名前ではなく、Personオブジェクト自体のリストを収集したいと思います

。 1つのすてきなラムバ式で。

これをすべて簡略化するために、グループ化の結果を保存する現在のソリューションをリンクしてから、繰り返して名前を収集します。

ArrayList<OtherPerson> members = new ArrayList<>(); 

members.add(new OtherPerson("Fred", IsoChronology.INSTANCE.date(1980, 6, 20), OtherPerson.Sex.MALE, "[email protected]")); 
members.add(new OtherPerson("Jane", IsoChronology.INSTANCE.date(1990, 7, 15), OtherPerson.Sex.FEMALE, "[email protected]")); 
members.add(new OtherPerson("Mark", IsoChronology.INSTANCE.date(1990, 7, 15), OtherPerson.Sex.MALE, "[email protected]")); 
members.add(new OtherPerson("George", IsoChronology.INSTANCE.date(1991, 8, 13), OtherPerson.Sex.MALE, "[email protected]")); 
members.add(new OtherPerson("Bob", IsoChronology.INSTANCE.date(2000, 9, 12), OtherPerson.Sex.MALE, "[email protected]")); 

Map<Integer, List<Person>> collect = members.stream().collect(groupingBy(Person::getAge)); 

Map<Integer, List<String>> result = new HashMap<>(); 

collect.keySet().forEach(key -> { 
      result.put(key, collect.get(key).stream().map(Person::getName).collect(toList())); 
}); 

Current solution

ない理想的な、私はよりエレガントで実行するソリューションを持っているしたい学習のために。

答えて

9

Collectors.groupingByとストリームをグループ化すると、カスタムでの値に縮小操作を指定することができますCollector 。ここでは、Collectors.mappingを使用する必要があります。これは関数(マッピングとは何か)とコレクタ(マッピングされた値の収集方法)を取ります。この場合、マッピングはPerson::getNameです。つまり、Personの名前を返すメソッド参照です。これをListに収集します。

Map<Integer, List<String>> collect = 
    members.stream() 
      .collect(Collectors.groupingBy(
       Person::getAge, 
       Collectors.mapping(Person::getName, Collectors.toList())) 
      ); 
+0

Ops、これは簡単でした! 乾杯! – lcardito

0

あなたは人の名前のリストにPersonのリストをマッピングするためにmappingCollectorを使用することができます。

Map<Integer, List<String>> collect = 
    members.stream() 
      .collect(Collectors.groupingBy(Person::getAge, 
              Collectors.mapping(Person::getName, Collectors.toList()))); 
1

また、Collectors.toMapを使用して、キー、値、およびマージ関数(存在する場合)のマッピングを提供することもできます。

Map<Integer, String> ageNameMap = 
    members.stream() 
      .collect(Collectors.toMap(
       person -> person.getAge(), 
       person -> person.getName(), (pName1, pName2) -> pName1+"|"+pName2) 
    ); 
関連する問題