StreamAPI Collectors.groupingBy为空集合而不是null

Nik*_*bak 4 java java-8 java-stream

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

很明显,结果映射具有分组属性中唯一的键.对于具有不定值集的类型,它必须像这样工作.但是enums/booleans /其他确定类型呢?

是否可以比下面的代码段更优雅地实现空集合的初始化?

if (entitiesByIsTest.get(true) == null) {
    entitiesByIsTest.put(true, new ArrayList());
}
Run Code Online (Sandbox Code Playgroud)

Hol*_*ger 10

如果您希望Boolean键和两个映射始终初始化,请使用partitioningBy具有所需属性的映射.

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

如果密钥是enum,则必须保留groupingBy,但您可以用以下内容替换后续get操作

List<Entity> value=map.computeIfAbsent(key, x->new ArrayList<>());
Run Code Online (Sandbox Code Playgroud)

它将构造并放置一个新的ArrayListif和only如果没有先前的映射并且在任何一种情况下都返回实际的映射值(不像putIfAbsent).

当然,您可以在一个急切的操作中添加所有缺席值:

EnumSet.allOf(KeyType.class).forEach(key->map.computeIfAbsent(key, x->new ArrayList<>()));
Run Code Online (Sandbox Code Playgroud)


Cla*_*ayn 5

您可以使用entitiesByIsTest.putIfAbsent(true,new ArrayList());它,只有在该键的地图中没有任何内容时才应添加新的空arraylist