2017-08-09 1 views
1

J'ai une liste d'objetsmoyenne des flux Android à partir d'une carte

class Result { 
    private String name; 
    private Map<String, Double> map; 

    // getters, constructor etc 
} 

Je veux groupe par un nom, et faire la moyenne des valeurs doubles dans une carte pour chaque touche. Chaque objet dans une liste a la carte avec les mêmes clés.

j'ai commencé en groupant par nom

Map <String, List<Result>> grouppedByName = Stream.of(results) 
     .collect(Collectors.groupingBy(Result::getName)); 

Je ne sais pas ce que la prochaine boucle en dehors de la régulière.

données de l'exemple:

INPUT: 

name = "Name 1" 
map: 
KEY1, 10 
KEY2, 1 

name = "Name 1" 
map: 
KEY1, 20 
KEY2, 7 

name = "Name 2" 
map: 
KEY1, 2 
KEY2, 3 
-------------- 
OUTPUT: 

name = "Name 1" 
map: 
KEY1, 15       (10+20)/2 = 15 
KEY2, 4       (1+7)/2 = 4 

name = "Name 2" 
map: 
KEY1, 2 
KEY2, 3 
+0

vous devriez être plus spécifique, montrez votre entrée, et montrez la production attendue – mac229

+0

J'ai ajouté un exemple de données – kkkkk

Répondre

1

Le procédé groupingBy produira Map<String, List<Result>>. Nous avons besoin d'une méthode pour transformer les valeurs List<Result> de cette carte à quelque chose de plus utile:

Map<String, Double> mapMerger(final List<Result> results) { 
    return results.stream() 
      .map(Result::getMap) 
      .map(Map::entrySet) 
      .flatMap(Set::stream) 
      .collect(groupingBy(Entry::getKey, averagingDouble(Entry::getValue))); 
} 

Cela va extraire toutes les entrées de type Entry<String, Double> de toutes les cartes de tous les résultats. Il va regrouper ces entrées dans une carte de chaque clé à la moyenne de toutes les valeurs pour cette clé.

Nous pouvons appliquer cette nouvelle méthode en créant un flux de la carte originale (grouppedByName dans votre question):

Map<String, Map<String, Double>> averagedByName = results.stream() 
     .collect(groupingBy(Result::getName)) 
     .entrySet().stream() 
     .collect(toMap(Entry::getKey, e -> mapMerger(e.getValue()))); 

Le vous devriez obtenir 15 si vous le faites:

double avg = averagedByName.get("Name 1").get("KEY1");