私は次のクラスを持っています
class Person {
public String name;
public int age;
public List<String> hobbies;
Person(String name, int age, List<String> hobbies)
{this.name = name; this.age = age; this.hobbies = hobbies;}
}
趣味の年齢マップを作成するにはどうすればよいMap<Integer, Set<String>>
ですか?
私が作り上げたJava8の方法は次のとおりです。
Map<Integer, Set<String>> collect8 = persons.stream()
.collect(
toMap(
p -> p.age,
p -> p.hobbies.stream().collect(toSet()),
(hobbies1, hobbies2) ->
Stream.concat(hobbies1.stream(), hobbies2.stream()).collect(toSet())
)
);
Collectors.groupingBy()
おそらくこれを行うためのより慣用的な方法はありますか?
関連する質問として、Javaストリームのないバージョンの方が読みやすいと思います。
Map<Integer, Set<String>> collect7 = new HashMap<>();
for(Person p: persons) {
Set<String> hobbies = collect7.getOrDefault(p.age, new HashSet<>());
hobbies.addAll(p.hobbies);
collect7.put(p.age, hobbies);
}
読みやすい場合は、非ストリームコードを使用する必要があります。特に、ここに見られるように、ストリーミングされたバージョンには、データの変換を伴う中間ストリームがないが、すぐにターミナル操作で終了する場合はどうでしょうか。
あなたがあなた自身に注意したように:Stream
解決策はあなたの現在の非解決策ほど読みにくいかもしれませんStream
。あなたの問題を解決するgroupingBy
かもしれないことは、あなたがあなたを変換したいとあなたが期待するかもしれないとして良いとして見ていないList
にSet
。
私は解決策を構築しgroupingBy
、mapping
そしてreducing
、しかし、そのソリューションは、簡単に読むことをしても、エラーが含まれなかったことではありません。詳細については、Java 8 stream.collect(... groupingBy(... Mapping(... reduce)))reducingBinaryOperator-usageを参照してください。Holgerが提供した回答を調べることをお勧めします。カスタムCollector
とJava9への小さなOutlookを使用したより単純なソリューションflatMapping
。これは私にとっては非ソリューションに近いものStream
です。
しかし、groupingBy
私が思いついた別の解決策は、実際に機能します:
Map<Integer, Set<String>> yourmap;
yourmap = personList.stream()
.flatMap(p -> p.hobbies.stream()
.flatMap(hobby -> Stream.of(new SimpleEntry<>(p.age, hobby)))
)
.collect(Collectors.groupingBy(Entry::getKey,
Collectors.mapping(Entry::getValue, Collectors.toSet())));
そのためには、次のインポートが必要です。
import java.util.AbstractMap.SimpleEntry;
import java.util.Map.Entry;
もちろん、あなたも取ることができるTuple
か、Pair
あなたが最も好きか何。
しかし、それでも、決して良くはありません。
私はあなたの現在の非解決Stream
策にとどまります。それはより読みやすく、それがすべきことをします。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加