Java 8 – Stream Collectors groupingBy examples
In this article, we will show you how to use Java 8 Stream Collectors to group by, count, sum and sort a List.
1. Group By, Count and Sort
1.1 Group by a List and display the total count of it.
package com.mkyong.java8; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; public class Java8Example1 { public static void main(String[] args) { //3 apple, 2 banana, others 1 List<String> items = Arrays.asList("apple", "apple", "banana", "apple", "orange", "banana", "papaya"); Map<String, Long> result = items.stream().collect( Collectors.groupingBy( Function.identity(), Collectors.counting() ); System.out.println(result);
output
papaya=1, orange=1, banana=2, apple=3
1.2 Add sorting.
package com.mkyong.java8; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; public class Java8Example2 { public static void main(String[] args) { //3 apple, 2 banana, others 1 List<String> items = Arrays.asList("apple", "apple", "banana", "apple", "orange", "banana", "papaya"); Map<String, Long> result = items.stream().collect( Collectors.groupingBy( Function.identity(), Collectors.counting() ); Map<String, Long> finalMap = new LinkedHashMap<>(); //Sort a map and add to finalMap result.entrySet().stream() .sorted(Map.Entry.<String, Long>comparingByValue() .reversed()).forEachOrdered(e -> finalMap.put(e.getKey(), e.getValue())); System.out.println(finalMap);
output
apple=3, banana=2, papaya=1, orange=1
2. List Objects
Examples to ‘group by’ a list of user defined Objects.
2.1 A Pojo.
package com.mkyong.java8; import java.math.BigDecimal; public class Item { private String name; private int qty; private BigDecimal price; //constructors, getter/setters
2.2 Group by the name + Count or Sum the Qty.
package com.mkyong.java8; import java.math.BigDecimal; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Java8Examples3 { public static void main(String[] args) { //3 apple, 2 banana, others 1 List<Item> items = Arrays.asList( new Item("apple", 10, new BigDecimal("9.99")), new Item("banana", 20, new BigDecimal("19.99")), new Item("orang", 10, new BigDecimal("29.99")), new Item("watermelon", 10, new BigDecimal("29.99")), new Item("papaya", 20, new BigDecimal("9.99")), new Item("apple", 10, new BigDecimal("9.99")), new Item("banana", 10, new BigDecimal("19.99")), new Item("apple", 20, new BigDecimal("9.99")) ); Map<String, Long> counting = items.stream().collect( Collectors.groupingBy(Item::getName, Collectors.counting())); System.out.println(counting); Map<String, Integer> sum = items.stream().collect( Collectors.groupingBy(Item::getName, Collectors.summingInt(Item::getQty))); System.out.println(sum);
output
//Group by + Count papaya=1, banana=2, apple=3, orang=1, watermelon=1 //Group by + Sum qty papaya=20, banana=30, apple=40, orang=10, watermelon=10
2.2 Group by Price – Collectors.groupingBy and Collectors.mapping example.
package com.mkyong.java8; import java.math.BigDecimal; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; public class Java8Examples4 { public static void main(String[] args) { //3 apple, 2 banana, others 1 List<Item> items = Arrays.asList( new Item("apple", 10, new BigDecimal("9.99")), new Item("banana", 20, new BigDecimal("19.99")), new Item("orang", 10, new BigDecimal("29.99")), new Item("watermelon", 10, new BigDecimal("29.99")), new Item("papaya", 20, new BigDecimal("9.99")), new Item("apple", 10, new BigDecimal("9.99")), new Item("banana", 10, new BigDecimal("19.99")), new Item("apple", 20, new BigDecimal("9.99")) ); //group by price Map<BigDecimal, List<Item>> groupByPriceMap = items.stream().collect(Collectors.groupingBy(Item::getPrice)); System.out.println(groupByPriceMap); // group by price, uses 'mapping' to convert List<Item> to Set<String> Map<BigDecimal, Set<String>> result = items.stream().collect( Collectors.groupingBy(Item::getPrice, Collectors.mapping(Item::getName, Collectors.toSet()) ); System.out.println(result);
output
19.99=[ Item{name='banana', qty=20, price=19.99}, Item{name='banana', qty=10, price=19.99} ], 29.99=[ Item{name='orang', qty=10, price=29.99}, Item{name='watermelon', qty=10, price=29.99} ], 9.99=[ Item{name='apple', qty=10, price=9.99}, Item{name='papaya', qty=20, price=9.99}, Item{name='apple', qty=10, price=9.99}, Item{name='apple', qty=20, price=9.99} //group by + mapping to Set 19.99=[banana], 29.99=[orang, watermelon], 9.99=[papaya, apple]
References
- Java 8 Stream Collectors JavaDoc
- Java – How to sort a Map
- Stackoverflow – Sort a Map
by values (Java)