2017-10-04 5 views
3

Est-il possible (de manière simple) de le changer en java8Stream? (S'il vous plaît ne pas commenter/répondre si vous voulez me dire que deux for sont meilleurs et toutes les boucles doivent être changées en cours d'eau, ce n'est pas un point)Création d'une carte à partir de la liste, où la clé fait partie d'un objet interne et externe

final Map<String, String> map = new HashMap<>(); 

for(final Person person: list) { 
    for(final Internal internal: person.getInternals()) { 
     final String key = person.getName() + internal.getKey(); 
     map.put(key, internal.getValue()); 
    } 
} 

Le principal problème est que je ne peux pas utiliser flatMap parce que je vais perdre les informations précédentes. Chaque création key est unique.

+2

vous n'avez pas besoin deuxième boucle du tout, car il est le même que: pour chaque personne, mettre son nom et dernière valeur interne la carte. Vous pouvez le faire en groupant le collecteur – mlecz

Répondre

5

Eh bien vous pouvez passer ceux le long via un Pair (je ne l'ai pas compilé ce bien, mais l'idée devrait être là)

list.stream() 
    .flatMap(person -> person.getInternals() 
         .stream() 
         .map(internal -> 
          Pair.of(person.getName() + internal.getKey(), internal.getValue())) 
    .collect(Collectors.toMap(Pair::getLeft, Pair::getRight)); 
+0

Oui, je sais, en utilisant un autre objet est une réponse ici, mais dans cette solution, nous avons besoin d'un second flux interne. J'espère qu'il y a une réponse avec une chaîne – ByeBye

+0

@ByeBye comment voulez-vous vous débarrasser de la deuxième itération? Je ne vous comprends pas du tout maintenant – Eugene

+1

@ByeBye this * is * "une chaîne" – Holger

2

Vous pouvez utiliser directement collect et si vous êtes sûr que chaque clé créé est unique, comme vous l'avez mentionné, l'accumulateur et combinateur sont simples à écrire:

Map<String, String> map = 
    list.stream().collect(HashMap::new, 
          (m, p) -> p.getInternals().forEach(i -> m.put(p.getName() + i.getKey(), i.getValue())), 
          Map::putAll);