Is it possible to summarize values with streams? For example, I have a class Dataset that divides a csv file for me into lines that contain values:
{customer=Max , articlenr=1234, paid=12}
{customer=Lisa , articlenr=21, paid=20}
{customer=Max , articlenr=19, paid=100}
Now I want to create a List with a Stream which gives me a list of my customers back(no other values), sorted by the sum what they have ever paid (in this example Max has paid 112 and Lisa 20). So I would expect getting Max first in the List and the Lisa.
Collect the sum of paid
to a Map<String, Integer>
, then stream the entries, sorting them in reverse order by paid, then collect the keys to a List
.
List<MyClass> records; // your list
List<String> customers = records.stream()
.collect(groupingBy(MyClass::getCustomer, Collectors.summingInt(MyClass::getPaid)))
.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.map(Map.Entry::getKey)
.collect(toList());
Here is a complete working example in Java 23.
record Payment( String name , int amount ) { }
List < Payment > payments =
List.of (
new Payment ( "Max" , 12 ) ,
new Payment ( "Lisa" , 20 ) ,
new Payment ( "Max" , 100 )
);
List < String > namesSortedByPaymentTotal =
payments
.stream ( )
.collect ( groupingBy ( Payment :: name , Collectors.summingInt ( Payment :: amount ) ) )
.entrySet ( ).stream ( )
.sorted ( Map.Entry. < String, Integer > comparingByValue ( ).reversed ( ) )
.map ( Map.Entry :: getKey )
.toList ( );
namesSortedByPaymentTotal.forEach ( System.out :: println );
When run:
Max
Lisa
To verify our work, modify that code.
payments
.stream ( )
.collect ( groupingBy ( Payment :: name , Collectors.summingInt ( Payment :: amount ) ) )
.entrySet ( ).stream ( )
.sorted ( Map.Entry. < String, Integer > comparingByValue ( ).reversed ( ) )
.forEach ( System.out :: println );
Max=112
Lisa=20