For example: I have a list of user objects with e-mails. I would like to collect the list of users with distinct e-mails (because two users with the same e-mail would be probably the same person, so I do not care about the differences). In other words, for each distinct key (e-mail), I want to grab the first value (user) found with that key and ignore the rest.
This is a code I have came up with:
public List<User> getUsersToInvite(List<User> users) {
return users
.stream()
// group users by their e-mail
// the resulting map structure: email -> [user]
.collect(Collectors.groupingBy(User::getEmail, LinkedHashMap::new, Collectors.toList()))
// browse each map entry
.entrySet()
.stream()
// get the first user object for each entry
.map(entry -> entry.getValue().get(0))
// collect such first entries into a list
.collect(Collectors.toList());
}
Is there some more elegant way?
You can use Collectors.toMap(keyMapper, valueMapper, mergeFunction)
, use the e-mail as key, user as value and ignore the key conflicts by always returning the first value. From the Map
, you can then get the users by calling values()
.
public List<User> getUsersToInvite(List<User> users) {
return new ArrayList<>(users.stream()
.collect(Collectors.toMap(User::getEmail,
Function.identity(),
(u1, u2) -> u1))
.values());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With