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.

Java8Example1.java

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.

Java8Example2.java

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.

Item.java

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.

Java8Examples3.java

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.

Java8Examples4.java

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

  1. Java 8 Stream Collectors JavaDoc
  2. Java – How to sort a Map
  3. Stackoverflow – Sort a Map by values (Java)

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

avatar
17 Comment threads
3 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
19 Comment authors
AmirhosseinRAJA SEKHAR CHITTIPROLUMarysandip soliyaAnonymous Recent comment authors
newest oldest most voted
murthy gandikota
Guest
murthy gandikota

In the example 1.2 above, the collection has to be sorted by key as well:

//Sort a map and add to finalMap
result.entrySet().stream()
.sorted(Map.Entry.comparingByValue()
.reversed()).sorted(Map.Entry.comparingByKey()).
forEachOrdered(e -> finalMap.put(e.getKey(), e.getValue()));

The resulting output is
{apple=3, banana=2, orange=1, papaya=1}

Thanks

oleg gavryliv
Guest
oleg gavryliv

Why do we need forEachOrdered here? Cause we use sequential stream.

Valentino
Guest
Valentino

Greate information!!!

Miguel Moreno
Guest
Miguel Moreno

What about doing the same example, but grouping by item name and summing the BigDecimal amounts?

Anonymous
Guest
Anonymous

Map<String, Double> result = items.stream()
.collect(Collectors.groupingBy(Item::getName, Collectors.summingDouble(i -> i.getPrice().doubleValue())));

Carol
Guest
Carol

Thanks, good examples

GOWRI SANKAR
Guest
GOWRI SANKAR

Nice set of examples. Thank you!

sandip soliya
Guest
sandip soliya

good examples for beginners

rpalvair
Guest
rpalvair

Good ;-)

Amirhossein
Guest
Amirhossein

great, these examples saved my time. thanx.

RAJA SEKHAR CHITTIPROLU
Guest
RAJA SEKHAR CHITTIPROLU

HI I have a list with 24 elements and I want to group them 4 individual lists with each list having 6 elements. how can i do it.

Mary
Guest
Mary

Hi, is very nice information, thanks for sharing. I would like to know how could be the best way to sort a map by the order of insertion of values from ArrayList? For example:

Here the list with the correct order of values
List list = new ArrayList();
list.add(“DELETE”);
list.add(“ADD”);
list.add(“CHANGE”);

and the insertion order map:
Map m = new HashMap();
m.put(“CHANGE”,”Attr1″);
m.put(“ADD”,”Attr2″);
m.put(“DELETE”,”Attr3″);
m.put(“CHANGE”,”Attr4″);

The expected result is as follow:
DELETE=Attr3,ADD=Attr2,CHANGE=Attr4

How can I apply the sort in the map taking as source the values of the list?

I hope be clear in my question. Thanks a lot

sandip soliya
Guest
sandip soliya

Very nice expatiation by examples.. it help well for beginners..Thank you

Andrea
Guest
Andrea

the last example is grouped by price, but is not sorted by increasing price, but literal. I have e three level grouped map, and i need to sort the middle level which has the key as float. How can i do it?

miri
Guest
miri

Thank you!
do you have the full examples in Github?

shameem
Guest
shameem

thanks, very helpfull

Eshkere
Guest
Eshkere

1.2 Should avoid using mutable variables like finalMap.

Venky
Guest
Venky

Very good explanation..Thank you

Rubin Roy
Guest
Rubin Roy

Is there a way to check grouping based on a set.
Eg. If there is a Set with Apple, banana, Orange, Papaya and if the ArrayList doesn’t have an apple is there a way to use Stream and grouping to get result like below

//Group by + Count
{
papaya=1, banana=2, apple=0, orange=1, watermelon=1//
}

Chinmay C
Guest
Chinmay C

Thanks!