如何将Java枚举按componentType映射为值为MatchType数组的ImmutableMap
解决方案
你原先使用的一对一toImmutableMap无法满足需求,该收集器遇到重复的key会直接抛出异常,不支持一对多的映射场景,需要先按componentType分组再转换为数组。
直接满足需求的写法
ImmutableMap<String, MatchType[]> findByComponentType = Arrays.stream(MatchType.values()) .collect(Collectors.groupingBy( matchType -> matchType.componentType, Collectors.collectingAndThen( Collectors.toList(), list -> list.toArray(new MatchType[0]) ) )) .entrySet() .stream() .collect(ImmutableMap.toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
调用findByComponentType.get("android.support.v4.app.Fragment")即可得到包含SUPPORT_FRAGMENT、SUPPORT_FRAGMENT_PRE_API23的枚举数组。
更优实现方案
如果你的项目依赖Guava 21及以上版本,更推荐使用ImmutableListMultimap实现,代码更简洁,性能也更好:
// 先构建多值映射 ImmutableListMultimap<String, MatchType> componentTypeMapping = Arrays.stream(MatchType.values()) .collect(ImmutableListMultimap.toImmutableListMultimap( matchType -> matchType.componentType, Function.identity() )); // 如无强制要求用数组作为值,直接用Multimap调用即可,返回不可变列表 // componentTypeMapping.get("android.support.v4.app.Fragment") // 如果必须要数组类型的值,再做一层转换 ImmutableMap<String, MatchType[]> findByComponentType = componentTypeMapping.asMap() .entrySet() .stream() .collect(ImmutableMap.toImmutableMap( Map.Entry::getKey, entry -> entry.getValue().toArray(new MatchType[0]) ));
Multimap是Guava专门为一对多映射场景设计的工具类,原生支持同一个key对应多个值,不需要手动处理分组逻辑,也避免了重复key的异常问题,日常使用比值为数组的Map更安全易用。
内容的提问来源于stack exchange,提问作者Johan
相关产品推荐
相关产品推荐

