2016-05-12 8 views
0

私はSet<Long>Listの各MyClassidを表しMap<Long, Set<Long>>Map<Long, List<MyClass>>(Javaの8ストリームを使用して)変換したいと思います。Javaの8ストリームマップ<ロング、リスト<MyClass>>マップする<ロング、設定<Long>>

私が試してみました:

myFirstMap.entrySet().stream() 
     .map(e -> e.getValue().stream() 
      .map(MyClass::getId) 
      .collect(Collectors.toSet())) 
をしかし、私は結果を取得する方法を見ることができません。

+2

あなたの編集は、その答えを無効に1年はここにいた。お願い、それはやめて。 – shmosel

答えて

4

Map.EntrySet<Long>のインスタンスをマッピングしています。元のマップのキーのトラックが失われていることを意味し、同じキーを持つ新しいマップにそれらを収集することはできません。

Map<Long, Set<Long>> result= 
    myFirstMap.entrySet().stream() 
     .map(e -> new AbstractMap.SimpleImmutableEntry<>(e.getKey(), 
       e.getValue().stream().map(MyClass::getId).collect(Collectors.toSet()))) 
     .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); 

代替変換を行うために、一つにmapcollectステップを融合することである。

最初のオプションはMap.Entry<Long, Set<Long>>インスタンスにMap.Entry<Long, List<MyClass>>インスタンスをマッピングし、新しいマップにエントリを収集することです右toMapコレクタに提供された値関数で:

Map<Long, Set<Long>> result= 
    myFirstMap.entrySet().stream().collect(Collectors.toMap(
     Map.Entry::getKey, 
     e -> e.getValue().stream().map(MyClass::getId).collect(Collectors.toSet()))); 

この方法では、新しいMap.Entryインスタンスを作成しないようにして取得しますしかし、より簡潔なコードでは、柔軟な柔軟性が失われます。その間に追加のストリーム操作を連鎖させることはできません。

0

Streamのオーバーヘッドなしに別の解決策は、このようなMap.forEach()を使用している:本当にこれを行うには、単に便利なメソッドです

Map<Long,Set<Long>> result = new HashMap<>(); 
myFirstMap.forEach((k,v) -> 
    result.put(k, v.stream() 
     .map(MyClass::getId) 
     .collect(Collectors.toSet()))); 

Map<Long,Set<Long>> result = new HashMap<>(); 
for (Map.Entry<Long, List<MyClass>> entry : myFirstMap.entrySet()) { 
    result.put(entry.getKey(), entry.getValue().stream() 
     .map(MyClass::getId) 
     .collect(Collectors.toSet())); 
} 
関連する問題