2017-08-24 6 views
2

私は以下の構造にMapを持っています。私はそのキーと値を反転したいと思います。Java8ストリームを使用したHashMapのキーを反転する

Map<String, List<String>> dataMap 

サンプルデータ:

acct01: [aa, ab, ad], 
acct02: [ac, ad] 
acct03: [ax, ab] 

は、このデータをに変換することにしたい、

aa: [acct01], 
ab: [acct01, acct03], 
ac: [acct02], 
ad: [acct01, acct02], 
ax: [acct03] 

は、Java 8があれば知りたい - 地図を変換するためのストリーム方法。

ストリームを使用して実装する方法を探してい

Map<String, List<String>> originalData = new HashMap<String, List<String>>(); 
     originalData.put("Acct01", Arrays.asList("aa", "ab", "ad")); 
     originalData.put("Acct02", Arrays.asList("ac", "ad")); 
     originalData.put("Acct03", Arrays.asList("ax", "ab")); 

     System.out.println(originalData); 
     Map<String, List<String>> newData = new HashMap<String, List<String>>(); 
     originalData.entrySet().forEach(entry -> { 
      entry.getValue().forEach(v -> { 
       if(newData.get(v) == null) { 
        List<String> t = new ArrayList<String>(); 
        t.add(entry.getKey()); 
        newData.put(v, t); 
       } else { 
        newData.get(v).add(entry.getKey()); 
       } 
      }); 
     }); 
     System.out.println(newData); 

入力と出力、 {Acct01=[aa, ab, ad], Acct02=[ac, ad], Acct03=[ax, ab]} {aa=[Acct01], ab=[Acct01, Acct03], ac=[Acct02], ad=[Acct01, Acct02], ax=[Acct03]}

(ストリームなし)での私の現在の実装。

+0

従来の方法を使用して実装されています..まだStream()を使用して実装する方法を探しています – Bala

答えて

3

エントリセットのストリームを取得し、キー/値ペアごとに1つのエントリにまとめ、値ごとにグループ化し、関連するキーをリストにまとめます。ここで

import static java.util.Arrays.asList; 
import static java.util.stream.Collectors.groupingBy; 
import static java.util.stream.Collectors.mapping; 
import static java.util.stream.Collectors.toList; 

import java.util.AbstractMap.SimpleImmutableEntry; 
import java.util.List; 
import java.util.Map; 
import java.util.Map.Entry; 

<K, V> Map<V, List<K>> invert(Map<K, List<V>> map) { 
    return map.entrySet() 
       .stream() 
       .flatMap(entry -> 
        entry.getValue() 
         .stream() 
         .map(value -> 
          new SimpleImmutableEntry<>(
           entry.getKey(), 
           value 
          ) 
         ) 
      ) 
       .collect(
        groupingBy(
         Entry::getValue, 
         mapping(
          Entry::getKey, 
          toList() 
        ) 
       ) 
      ); 
} 
2

は、Java 8ストリームライブラリによって溶液である:StreamEx

newData = EntryStream.of(originalData).invert().flatMapKeys(k -> k.stream()).grouping(); 
0

あなたの現在の実装では、すでにJava8の機能に依存しています。 forEachメソッドがJ8のいくつかのデータ構造に追加されました。ストリームを使用することはできますが、ストリームの利点の多くは、遅延、フィルタリング、これはキーの再マッピングには適用されません。

実際にしたい場合は、すべての.forEachインスタンスを.stream().forEachに変更することで、カップルストリームに振りかけることができます。

2

Eclipse Collectionsのようなサードパーティのライブラリを使用している場合は、ListMultimap(各キーの値はList)を使用できます。マルチマップはflip()です。だから、これは動作します:

MutableListMultimap<String, String> originalData = Multimaps.mutable.list.empty(); 
originalData.putAll("Acct01", Arrays.asList("aa", "ab", "ad")); 
originalData.putAll("Acct02", Arrays.asList("ac", "ad")); 
originalData.putAll("Acct03", Arrays.asList("ax", "ab")); 
System.out.println(originalData); 

MutableBagMultimap<String, String> newData = originalData.flip(); 
System.out.println(newData); 

入力:{Acct03=[ax, ab], Acct02=[ac, ad], Acct01=[aa, ab, ad]}

出力:{ac=[Acct02], ad=[Acct02, Acct01], aa=[Acct01], ab=[Acct03, Acct01], ax=[Acct03]}

flip()は、各キーが値のBagを持つことができBagMultimapを返すことに注意してください。 Bagは、順序付けられておらず、重複を許す特別なデータ構造です。

注:私はEclipse Collectionsのコミッターです。

関連する問題