I am wondering if there is already an implemented feature in streams (or Collectors) which first groups a stream by an attribute and then returns the first element in the list sorted by another attribute. E.g. the following code tries to group a stream of objects using the first attribute and then wants to collect that object which has the highest value of the second attribute.
class MyClass{
String att1;
String att2;
}
Now, I want to achieve something like this with Stream myClassStream -
Map<String,MyClass> myMap = myClassStream().collect(Collectors.groupingBy(MyClass::getAtt1)); //Now I want to do Sorting after grouping to collect only the element which has the highest value of attr2.
My code using simple for loop is:
Map<String, MyClass> postAnalyticsMap = new HashMap<>();
for (MyClass post : myClassList) {
if (post.get(post.getAtt1()) == null) {
post.put(post.getAtt1(), post);
} else {
MyClass existingClass = postAnalyticsMap.get(post.getAtt1());
if (existingPostAnalytics.getAtt2() < post.getAtt2()) {
postAnalyticsMap.put(post.getAtt1(), post);
}
}
}
Any help will be much appreciated.
Use the toMap with merge function to find the max element on second attribute
Map<String, MyClass> map = myClassList.stream()
.collect(Collectors.toMap(MyClass::getAtt1, Function.identity(),
BinaryOperator.maxBy(Comparator.comparing(MyClass::getAtt2))));
You can do something like this:
myClassStream()
.collect(Collectors.groupingBy(MyClass::getAtt1,
Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparing(MyClass::getAtt2)),
myClass -> myClass.map(MyClass::getAtt2).orElse(""))));
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