2017-09-28 6 views
2

Comment utiliser les flux Java 8 pour échanger des clés dans cette carte de cartes? Ou au moins nettoyer ce gâchis un peu ...Changement de clés dans une carte de cartes

Map<Type1, Map<Type2, String>> to Map<Type2, Map<Type1, String>> 

pour les boucles utilisant imbriquée (non testé):

Map<Type1, Map<Type2, String>> map ... 
    Map<Type2, Map<Type1, String>> map2 = new HashMap<>(); 
     for (Type 1 type1 : map.keySet()) { 
      for(Entry<Type2, String> entry : map.get(type1)) { 
       if (map2.get(entry.key() == null) { 
        map2.push(entry.key(), new HashMap<Type1, String>(); 
      } 
      map2.get(entry.key()).put(type1, entry.value(); 
     } 
    } 

Je pense Jusqu'à présent, vous devrez carte rabat dans toutes les combinaisons uniques de Type1, Type2 et String et stockent cet ensemble dans une sorte de collection intermédiaire.

Certainement mal:

map.entrySet().stream().flatMap(t -> <Type1, Type2, 
String>).collect(Collectors.toMap(t -> t.Type2, Collectors.toMap(t -> 
t.type1, t->t.String)) 

Répondre

2

Je dirigerait clairement des cours d'eau pour ce type de problème. Ce serait juste difficile à lire. plutôt envisager la rationalisation de votre code à l'aide d'autres Java 8 ajouts - Map#forEach et Map#computeIfAbsent:

map.forEach((t1, e) -> 
    e.forEach((t2, v) -> 
      result.computeIfAbsent(t2, x -> new HashMap<>()).put(t1, v) 
    ) 
); 
+1

C'est sans aucun doute une meilleure solution! En fait, j'ai fini par utiliser un type intermédiaire, une liste d'une classe de conteneur, puis j'ai utilisé streams + flatmap pour l'obtenir dans le format désiré. Si vous avez l'impression de combattre la structure de données, il y a probablement une meilleure solution. –

2

Misha déjà vous a montré la solution simple. Si vous voulez vraiment utiliser Stream s il pourrait ressembler à ceci:

public static <S, T> Map<T, Map<S, String>> convertStream(Map<S, Map<T, String>> map) { 
    return map.entrySet().stream().flatMap(m1 -> m1.getValue().entrySet() 
               .stream().map(e -> new Object() { 
    final T outer = e.getKey(); 
    final Map<S, String> map; 
    { 
     map = new HashMap<>(); 
     map.put(m1.getKey(), e.getValue()); 
    } 
    })).collect(Collectors.toMap(o -> o.outer, o -> o.map, (m1, m2) -> { 
    m1.putAll(m2); 
    return m1; 
    })); 
} 
0
Map<Type2, Map<Type1, Object>> finalAnswer = map.entrySet().stream() 
.collect(()->new HashMap<Type2,Map<Type1,Object>>(), 
      (mapAccumulator, left)->{    
       for(Entry<?, ?> leftEntry : left.getValue().entrySet()){ 
        Map<Type1,Object> tempMap = new HashMap<>(); 
        tempMap.put(left.getKey(), leftEntry.getValue()); 
        mapAccumulator.put((Type2) leftEntry.getKey(), tempMap); 
       } 

      /*accumulator*/}, 
     (mapLeft,mapRight)->{mapLeft.putAll(mapRight); /*combiner*/}); 

map.entrySet().forEach(System.out::println);