Is it possible use Collectors.groupingBy()
with Collectors.counting()
to count to the field of a custom object instead of creating a map and transforming it afterwards.
I have a list of users, like this:
public class User {
private String firstName;
private String lastName;
// some more attributes
// getters and setters
}
I want to count all users with the same first and last name. Therefore I have custom object looking like this:
public static class NameGroup {
private String firstName;
private String lastName;
private long count;
// getters and setters
}
I can collect the name groups using this:
List<NameGroup> names = users.stream()
.collect(Collectors.groupingBy(p -> Arrays.asList(p.getFirstName(), p.getLastName()), Collectors.counting()))
.entrySet().stream()
.map(e -> new NameGroup(e.getKey().get(0), e.getKey().get(1), e.getValue()))
.collect(Collectors.toList());
With this solution I have to group the users first to a map and transform it afterwards to my custom object. Is it possible to count all names directly to nameGroup.count
to avoid iterating twice over the list (or map) and improve the performance?
collect() is one of the Java 8's Stream API's terminal methods. It allows us to perform mutable fold operations (repackaging elements to some data structures and applying some additional logic, concatenating them, etc.) on data elements held in a Stream instance.
Collector collectingAndThen(Collector downstream, Function finisher): This method allows us to perform another operation on the result after collecting the input element of collection.
You could collect directly to NameGroup.count
, but it would be less efficient than what you have, not more.
Internally, the map is being used to maintain a data structure that can efficiently track the name combinations and map them to counts which are updated as more matches are found. Reinventing that data structure is painful and unlikely to result in meaningful improvements.
You could try to collect NameGroups directly in the map instead of going via a count, but most approaches for that would, again, be more expensive than what you have now, and certainly much more awkward.
Honestly: what you have now is perfectly good, and not inefficient in any ways that are important. You should almost certainly stick to what you have.
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