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);