How to Group a List of Objects by Field in Java

Suppose we have a Dog class in Java with breed and name attributes.

class Dog {
  int id;
  String breed;

  Dog(int id, String breed) { = id;
    this.breed = breed;
  int getId() { return; }
  String getBreed() { return this.breed; }

And let’s suppose we have a list of Dog objects.

List<Dog> lst = new ArrayList<Dog>();
lst.add(new Dog(1, "corgi"));
lst.add(new Dog(2, "shih tzu"));
lst.add(new Dog(3, "corgi"));
lst.add(new Dog(4, "corgi"));
lst.add(new Dog(5, "husky"));
lst.add(new Dog(6, "shih tzu"));

How can we group these Dog objects by the breed field?

Using a for loop

We can do this quite easily using a simple for loop and conditional.

Map<String, List<Dog>> grouped = new HashMap<String, List<Dog>>();
for (Dog dog : lst) {
  String key = dog.breed;
  if (!grouped.containsKey(key)) {
    grouped.put(key, new ArrayList<Dog>());

Using the Stream API’s groupingBy()

In Java 8, we can use stream() and collect() to achieve the same functionality.

Map<String, List<Dog>> grouped = -> o.breed));

We can generalize this function using this same Collectors.groupingBy() method.

public static <E, K> Map<K, List<E>> groupBy(List<E> list, Function<E, K> keyFunction) {
  return Optional.ofNullable(list)
Map<String, List<Dog>> grouped = groupBy(lst, Dog::getBreed);