How to group objects by their property using Java 8 stream

Introduction

Here we will see an example on how to group objects by their property using Java 8 stream API. GROUP BY is a very useful aggregate operation in SQL, which allows us to group records on certain criteria and Java 8 directly allows us to do GROUP BY in Java by using Collectors.groupingBy() method. We have various overloaded version of groupingBy() method which allow us to perform grouping objects concurrently by using concurrent Collectors.

Let’s say you have Book object with attributes or properties as title and author and you want to group books by their title or author. We can do it by using a for loop, checking each book and putting them on a list of HashMap with the same title or author, but in Java 8, we don’t need to perform such operations, we have a much cleaner solution.

Prerequisites

At least Java 8

Group Objects in Java 8

Here we will create sample program that will group Book objects on their property – title.

Book Class

Book class has two attributes – title and author. You can add more attributes as per your needs.

package com.roytuts.java.group.objects.stream.lambda;

public class Book {
	private String title;
	private String author;

	public Book(String title, String author) {
		this.title = title;
		this.author = author;
	}

	public String getTitle() {
		return title;
	}

	public String getAuthor() {
		return author;
	}

	@Override
	public String toString() {
		return "Book [title=" + title + ", author=" + author + "]";
	}

}

Group Books

Now we will create some sample Book objects and apply Java 8’s stream API to group on the title.

package com.roytuts.java.group.objects.stream.lambda;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class JavaGroupObjectsByPropertyInList {

	public static void main(String[] args) {
		List<Book> books = new ArrayList<>();

		books.add(new Book("Java", "James Gosling"));
		books.add(new Book("C++", "Bjourn Stroustup"));
		books.add(new Book("C", "Denish Ritche"));
		books.add(new Book("Databse", "C J Date"));
		books.add(new Book("Java", "James Gosling"));
		books.add(new Book("C", "Yashavant Kanetkar"));

		Map<String, List<Book>> bookMap = books.stream().collect(Collectors.groupingBy(Book::getTitle));

		bookMap.forEach((k, v) -> System.out.println(k + " => " + v));
	}

}

Testing the Program

Now executing the above main class will give you the following output.

Java => [Book [title=Java, author=James Gosling], Book [title=Java, author=James Gosling]]
C++ => [Book [title=C++, author=Bjourn Stroustup]]
C => [Book [title=C, author=Denish Ritche], Book [title=C, author=Yashavant Kanetkar]]
Databse => [Book [title=Databse, author=C J Date]]

We have two Java books under title Java and two C books under title C.

Download Source Code

Thanks for reading.

Related posts

Leave a Comment