J'ai deux listes différentes de mêmes objets mais de propriétés différentes et avec un identifiant commun dans ces objets. Je voudrais parcourir la première liste et obtenir l'objet correspondant de la seconde (qui a des propriétés communes), puis encapsuler ces objets et enfin ajouter cet objet à une liste en utilisant Java Streams.
Voici l'exemple que j'ai pris.
private class Person {
private String name;
private boolean isSenior;
private Person(String name, boolean isSenior) {
this.name = name;
this.isSenior = isSenior;
}
public String getName() {
return name;
}
public boolean isSenior() {
return isSenior;
}
@Override
public String toString() {
return name + ": " + isSenior;
}
}
private class PersonWrapper {
private Person jrPerson;
private Person srPerson;
private PersonWrapper(Person jrPerson, Person srPerson) {
this.jrPerson = jrPerson;
this.srPerson = srPerson;
}
public Person getJrPerson() {
return jrPerson;
}
public Person getSrPerson() {
return srPerson;
}
@Override
public String toString() {
return jrPerson.toString() + "-" + srPerson.toString();
}
}
Maintenant, dans la classe principale, je vais créer deux instances de liste comme celle-ci
List<Person> jrPersons = new ArrayList<>();
List<Person> srPersons = new ArrayList<>();
et ajoutez les objets de la manière suivante
jrList.add(new Person("John", false));
jrList.add(new Person("Paul", false));
jrList.add(new Person("Mike", false));
seniorList.add(new Person("John", true));
seniorList.add(new Person("Paul", true));
seniorList.add(new Person("Mike", true));
Maintenant, je veux parcourir la jrList et trouver l'objet Person correspondant dans la srList (même nom). Ensuite, j'emballerais ces objets en tant que PersonWrapper
et cet objet dans une liste.
Jusqu'à présent, c'est ce que j'ai fait
List<PersonWrapper> wrapperList = new ArrayList<>();
jrList.forEach(jr -> seniorList.stream().filter(sr -> jr.getName().equals(sr.getName())).map(sr -> new PersonWrapper(jr, sr)).collect(Collectors.toList()));
Maintenant, je voudrais savoir comment la Collectors.toList()
peut être remplacée par wrapperList
ou comment la sortie de Collectors.toList()
peut être ajoutée à wrapperList
.
Veuillez m'aider à y parvenir.
Alors que Lino's la réponse est certainement correcte. Je dirais que si un objet personne donné dans jrList
ne peut avoir qu'une seule correspondance correspondante dans seniorList
maximum, en d'autres termes, s'il s'agit d'une relation 1-1, vous pouvez améliorer la solution donné par Lino en trouvant la première correspondance comme suit:
List<PersonWrapper> resultSet = jrList.stream()
.map(p -> seniorList.stream()
.filter(sr -> p.getName().equals(sr.getName()))
.findFirst()
.map(q -> new PersonWrapper(p, q))
.get())
.collect(Collectors.toList());
ou s'il n'y a aucune garantie que chaque personne dans jrList
aura une correspondance correspondante dans seniorList
, remplacez la requête ci-dessus par:
List<PersonWrapper> resultSet = jrList.stream()
.map(p -> seniorList.stream()
.filter(sr -> p.getName().equals(sr.getName()))
.findFirst()
.map(q -> new PersonWrapper(p, q))
.orElse(null))
.filter(Objects::nonNull)
.collect(Collectors.toList());
La différence est que maintenant au lieu d'appeler get()
sur le résultat de findFirst()
nous fournissons une valeur par défaut avec orElse
au cas où findFirst
ne trouverait pas la valeur correspondante puis nous filter
les null
valeurs dans l'opération intermédiaire suivante car elles ne sont pas nécessaires.
Au lieu d'utiliser un forEach
utilisez simplement des flux depuis le début:
List<PersonWrapper> wrapperList = jrList.stream()
.flatMap(jr -> seniorList.stream()
.filter(sr -> jr.getName().equals(sr.getName()))
.map(sr -> new PersonWrapper(jr, sr))
)
.collect(Collectors.toList());
En utilisant flatMap
, vous pouvez aplatir un flux de flux (Stream<Stream<PersonWrapper>>
) en un seul flux (Stream<PersonWrapper>
)
Si vous ne pouvez pas instancier wrapperList
par vous-même ou si vous devez vraiment y ajouter. Vous pouvez modifier l'extrait ci-dessus comme suit:
List<PersonWrapper> wrapperList = new ArrayList<>();
jrList.stream()
.flatMap(jr -> seniorList.stream()
.filter(sr -> jr.getName().equals(sr.getName()))
.map(sr -> new PersonWrapper(jr, sr))
)
.forEach(wrapperList::add);