2017-05-30 154 views
0

我有一個HashMap<Integer, List<String>>作爲輸入,e.g:轉換一個HashMap <整數,列表<String>>到的HashMap <字符串,HashSet的<Integer>>

3 : a, b, c 
6 : b, c 
9 : a, c 
12 : b ,c 

我想將其轉換爲HashMap<String, HashSet<Integer>>爲例如

a : 3, 9 
b : 3, 6, 12 
c : 3, 6, 9, 12 

該怎麼辦?

+1

你嘗試過這麼遠嗎? – Jens

+0

以前的Stack Overflow已經覆蓋了類似的任務,並且有很好的答案,但是他們很難搜索(我沒有很容易找到一個例子)。我仍然鼓勵你嘗試你的搜索技巧和運氣。 –

+1

[Java8流的可能的重複:將值作爲列表移調的映射](https://stackoverflow.com/questions/38471056/java8-streams-transpose-map-with-values-as-list) –

回答

1

只看重複鏈接。

這是最後的解決方案,我已經

private HashMap<String, HashSet<Integer>> process(HashMap<Integer, List<String>> input) { 
    return input.entrySet().stream() 
      .flatMap(entry -> entry.getValue().stream().map(s -> new SimpleEntry<>(entry.getKey(), s))) 
      .collect(Collectors.groupingBy(SimpleEntry::getValue, HashMap::new, 
       Collectors.mapping(SimpleEntry::getKey, Collectors.toCollection(HashSet::new)))); 
    } 
+0

這是對鏈接問題的答案進行了細微調整以適應您的特定要求(特別要求在結果地圖中將值設置爲值)。 –

2

這應該有助於

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

initMap.put(3, new ArrayList<String>(Arrays.asList("a", "b", "c"))); 
initMap.put(6, new ArrayList<String>(Arrays.asList("b", "c"))); 
initMap.put(9, new ArrayList<String>(Arrays.asList("a", "c"))); 
initMap.put(12, new ArrayList<String>(Arrays.asList("b", "c"))); 

Map<String, Set<Integer>> finalMap = new HashMap<>(); 

initMap.forEach((key, values) -> { 
    values.forEach(val -> { 
    Object o = finalMap.containsKey(val) ? 
      finalMap.get(val).add(key) : 
      finalMap.put(val, new HashSet<Integer>(Arrays.asList(key))); 
    }); 
}); 
1

下面是一個例子,以測試沿:

import java.util.Arrays; 
import java.util.HashMap; 
import java.util.HashSet; 
import java.util.List; 
import java.util.stream.Collectors; 

import org.junit.Assert; 
import org.junit.Test; 

public class SoTests { 
    @Test 
    public void so01() { 
     HashMap<Integer, List<String>> input = new HashMap<>(4); 
     input.put(3, Arrays.asList("a", "b", "c")); 
     input.put(6, Arrays.asList("b", "c")); 
     input.put(9, Arrays.asList("a", "c")); 
     input.put(12, Arrays.asList("b", "c")); 

     HashMap<String, HashSet<Integer>> output = process(input); 

     HashMap<String, HashSet<Integer>> expectedOutput = new HashMap<>(3); 
     expectedOutput.put("a", new HashSet<>(Arrays.asList(3, 9))); 
     expectedOutput.put("b", new HashSet<>(Arrays.asList(3, 6, 12))); 
     expectedOutput.put("c", new HashSet<>(Arrays.asList(3, 6, 9, 12))); 
     Assert.assertEquals(expectedOutput, output); 
    } 

    private HashMap<String, HashSet<Integer>> process(HashMap<Integer, List<String>> input) { 
     return input.entrySet().stream() // 
      .flatMap(entry -> entry.getValue().stream().map(s -> new IntegerAndString(entry.getKey(), s))) // 
      .collect(Collectors.groupingBy(IntegerAndString::getString, HashMap::new, // 
       Collectors.mapping(IntegerAndString::getInteger, Collectors.toCollection(HashSet::new)))); 
    } 

    private static class IntegerAndString { 
     private final Integer integer; 
     private final String string; 

     IntegerAndString(Integer integer, String string) { 
      this.integer = integer; 
      this.string = string; 
     } 

     Integer getInteger() { 
      return integer; 
     } 

     String getString() { 
      return string; 
     } 
    } 
} 

實際的邏輯是在process方法。醜陋的IntegerAndString類是由於缺乏Java中的元組類型。您可以使用一些庫,如javatuples

+1

感謝您的代碼片段。你可以給它添加一些解釋。 ? (流媒體部分) –

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

    intHM.put(3, new ArrayList<String>(Arrays.asList("a","b","c"))); 

    intHM.put(6, new ArrayList<String>(Arrays.asList("b","c"))); 

    intHM.put(9, new ArrayList<String>(Arrays.asList("a","c"))); 

    intHM.put(12, new ArrayList<String>(Arrays.asList("b","c"))); 

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

    Iterator<Entry<Integer,List<String>>> iterator = intHM.entrySet().iterator(); 

    while (iterator.hasNext()) { 

     Map.Entry<Integer,List<String>> entry = (Map.Entry<Integer,List<String>>) iterator.next(); 

     for(String str: entry.getValue()) 
     { 

      if (StringHM.containsKey(str)) 
       StringHM.get(str).add(entry.getKey()); 
      else 
       StringHM.put(str, new ArrayList<Integer>(Arrays.asList(entry.getKey()))); 

     } 
    } 

    Iterator<Entry<String,List<Integer>>> StringIterator = StringHM.entrySet().iterator(); 

    while (StringIterator.hasNext()) { 

     Map.Entry<String,List<Integer>> entry = (Map.Entry<String,List<Integer>>) StringIterator.next(); 

     System.out.print(entry.getKey()+" "); 

     for(Integer i: entry.getValue()) 

      System.out.print(i+" "); 

     System.out.println(); 
    } 
相關問題