4 votes

Comment mapper ceci en Java 8 en utilisant l'API de flux ?

Ok, donc j'ai un List<Person> . et chaque Person a un List<String> c'est une liste de numéros de téléphone que cette personne possède.

Voici donc la structure de base :

public class Person {

    private String name;
    private List<String> phoneNumbers;

    // constructors and accessor methods

}

Je voudrais créer un Map<String, Person> où la clé est chaque numéro de téléphone que la personne possède, et la valeur est la personne réelle.

Donc, pour mieux expliquer. Si j'avais ceci List<Person> :

Person bob = new Person("Bob");
bob.getPhoneNumbers().add("555-1738");
bob.getPhoneNumbers().add("555-1218");

Person john = new Person("John");
john.getPhoneNumbers().add("518-3718");
john.getPhoneNumbers().add("518-3115");
john.getPhoneNumbers().add("519-1987");

List<Person> list = new ArrayList<>();
list.add(bob);
list.add(john);

et j'ai invoqué cette méthode. Cela me donnerait le résultat suivant Map<String, Person>

Map<String, Person> map = new HashMap<>();
map.put("555-1738", bob);
map.put("555-1218", bob);

map.put("518-3718", john);
map.put("518-3115", john);
map.put("519-1987", john);

J'aimerais savoir comment y parvenir en utilisant la fonction stream car je sais déjà comment le faire en utilisant l'API. for les boucles et autres.

5voto

Simon Points 4883

Si vous avez une liste de personnes appelées persons et une classe appelée PhoneNumberAndPerson (vous pouvez utiliser une Tuple ou Pair à la place)

Voici les étapes :

Pour chaque personne, prenez chaque numéro de téléphone de cette personne. Pour chacun de ces numéros de téléphone, créez une nouvelle instance de PhoneNumberAndPerson et l'ajouter à une liste. Utilisez flatMap pour créer une seule liste à partir de toutes ces petites listes. Pour créer une Map à partir de cette liste vous fournissez une fonction pour extraire une clé d'une PhoneNumberAndPerson et une autre fonction pour extraire un Person de ce même PhoneNumberAndPerson .

persons.stream()
    .flatMap(person -> person.getPhoneNumbers().stream().map(phoneNumber -> new PhoneNumberAndPerson(phoneNumber, person)))
    .collect(Collectors.toMap(pp -> pp.getPhoneNumber(), pp -> pp.getPerson()));

4voto

Rustam Points 96

Sans classe supplémentaire et sans création préalable de carte :

Map<String, Person> result = list.stream().collect(HashMap::new,
     (map, p) -> p.getPhoneNumbers().forEach(phone -> map.put(phone, p)), HashMap::putAll);

2voto

GaruGaru Points 81

Sans créer d'autres classes, j'opterais pour quelque chose comme ça :

    Map<String, String> map = new HashMap<>();
    list.stream().forEach(p -> p.getPhoneNumbers().forEach(n -> map.put(n, p.getName())));

Edit : Comme suggéré par Simon, vous pouvez utiliser la méthode collect, mais cela peut être délicat si vous voulez créer une carte en utilisant la classe que vous avez fournie, avec une classe plus simple ( sans utiliser List mais juste une simple String afin de stocker le numéro) vous pouvez simplement appeler le code ci-dessous qui retourne une Map

list.stream().collect(Collectors.toMap(Person::getPhoneNumber, Person::getName));

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X