Group List Elements into a Map Using Java

In this article, let’s check how we can group elements in a given List to a Java Map.

Suppose we have a User class having name and age fields, and we create three User objects and keep them in a list.

We want a map with user.age as map key, and list of user objects as map value.

  @Data
  @NoArgsConstructor
  @AllArgsConstructor
  public class User {
      private String name;
      private Integer age;
  }
  // ...

    User user1 = new User("Jack", 25);
    User user2 = new User("Tom", 30);
    User user3 = new User("Jane", 30);
    List<User> list = Arrays.asList(user1, user2, user3);
    Map<Integer, List<User>> map = new HashMap<>();

Plain Java For Loop

    for (User u : list) {
        if (!map.containsKey(u.getAge())) {
            map.put(u.getAge(), new ArrayList<>(Arrays.asList(u)));
        } else {
            map.get(u.getAge()).add(u);
        }
    }
    log.info("map with duplicates: {}", map);

Java 8 Stream groupingBy()

    map = list.stream()
        .collect(Collectors.groupingBy(User::getAge,
            Collectors.mapping(Function.identity(), Collectors.toList())));
    log.info("map with duplicates: {}", map);

Apache Commons MultiValuedMap

If you have Apache Commons Collections library in your classpath, you can also use MultiValuedMap, which is a map that holds a collection of values against each key.

A MultiValuedMap is a Map with slightly different semantics:

  • Putting a value into the map will add the value to a Collection at that key.
  • Getting a value will return a Collection, holding all the values put to that key.
    MultiValuedMap<Integer, User> apacheCommonMultiMap = MultiMapUtils.newListValuedHashMap();
    list.forEach(
            e -> apacheCommonMultiMap.put(e.getAge(), e)
    );
    log.info("apacheCommonMultiMap: {}", apacheCommonMultiMap);

Google Guava Multimaps

If you have Google Guava library in your classpath, you can also use Multimaps. It has the same semantics with MultiValuedMap in Apache Commons Collections

    ImmutableListMultimap<Integer, User> guavaMultiMap = Multimaps.index(list, User::getAge);
    log.info("guavaMultiMap: {}", guavaMultiMap);

Read More