Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

StreamAPI Collectors.groupingBy empty collection instead of null

List<Entity> entities = ...
Map<Boolean, List<Entity>> entitiesByIsTest = entities.stream()
                        .collect(Collectors.groupingBy(Entity::isTest));

It is obvious, that the result map has the only keys which is present in grouping property. It must work like this for types with infinitive set of values. But what about enums/booleans/other determined types?

Is it possible to implement initialization of empty collections more elegantly than in snippet below?

if (entitiesByIsTest.get(true) == null) {
    entitiesByIsTest.put(true, new ArrayList());
}
like image 558
Nikolay Shabak Avatar asked Oct 12 '16 13:10

Nikolay Shabak


1 Answers

If you want Boolean keys and both mappings always initialized, use partitioningBy, which has exactly the desired properties.

Map<Boolean, List<Entity>> entitiesByIsTest = entities.stream()
                        .collect(Collectors.partitioningBy(Entity::isTest));

If the key is an enum, you have to stay with groupingBy, but you may replace the subsequent get operations with

List<Entity> value=map.computeIfAbsent(key, x->new ArrayList<>());

which will construct and put a new ArrayList if and only if there was no previous mapping and return the actual mapped value in either case (unlike putIfAbsent).

Of course, you could add all absent values in one eager operation instead:

EnumSet.allOf(KeyType.class).forEach(key->map.computeIfAbsent(key, x->new ArrayList<>()));
like image 67
Holger Avatar answered Nov 03 '22 23:11

Holger