首页IT科技Java8 Stream流Collectors.toMap当key重复时报异常(IllegalStateException)

Java8 Stream流Collectors.toMap当key重复时报异常(IllegalStateException)

时间2025-09-19 07:05:43分类IT科技浏览6039
导读:一、问题 在使用Collectors.toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper (两个参数的)时,如果 key 有重复,则会报异常(Illega...

一                、问题

在使用Collectors.toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper)(两个参数的)时                ,如果 key 有重复                        ,则会报异常(IllegalStateException)                。

二                        、分析

Collectors.toMap()是有三个重载方法(2个参数        ,3个参数            ,4个参数)                        ,如下所示:

keyMapper:Key 的映射函数

valueMapper:Value 的映射函数

mergeFunction:当 Key 冲突时            ,调用的合并方法

mapSupplier:Map 构造器        ,在需要返回特定的 Map 时使用

1        、toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper); 2            、toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper, BinaryOperator<U> mergeFunction); 3                        、toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier);

①第一个                        ,如果key冲突了                ,会默认抛出异常

public static <T, K, U> Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper) { return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new); }

②第二个    ,如果key冲突了                        ,可以按照指定的要求进行合并(取第一个还是最后一个)

public static <T, K, U> Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper, BinaryOperator<U> mergeFunction) { return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new); }

③第三个可以自定义异常方法和 Map 类型

public static <T, K, U, M extends Map<K, U>> Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier) { BiConsumer<M, T> accumulator = (map, element) -> map.merge(keyMapper.apply(element), valueMapper.apply(element), mergeFunction); return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID); }

举例如下:

三            、解决方法

避免出现重复时报异常                    ,建议选用第二个带3个参数的 toMap 方法(一般取前面value的值,或者取后面放入的 value 值则覆盖先前的 value 值)                        。

1        、选用重复 key 中第一个 value 值

Map<String, Object> result = list.stream().flatMap(m -> m.entrySet().stream()) .collect(Collectors.toMap(m -> m.getKey(), m -> m.getValue(), (v1, v2) -> v1));

2                        、选用重复 key 中最后一个 value 值 (若重复 key 元素有2个则取第二元素的 value                    ,若有3个则取第三个的 value                        ,…)

Map<String, Object> result = list.stream().flatMap(m -> m.entrySet().stream()) .collect(Collectors.toMap(m -> m.getKey(), m -> m.getValue(), (v1, v2) -> v2));

3                、指定取哪个value值或哪种类型的value值(具体的实践根据具体的业务来操作数据即可)

4    、直接返回一个给定的默认值

四                        、注意事项

1                    、key 不能有重复    ,如果重复则需要使用合并函数取默认值                ,否则会报错                        ,因为 Map 的 key 不能重复        。 2、合并函数有两个参数        ,第一个参数是重复数据中的第一个元素            ,第二个参数是重复数据中的最后一个元素                        ,可以用来返回默认值            。 3                    、使用合并函数可以配合排序函数            ,根据排序规则正序                        、倒序        ,取每组重复数据中最近或最远的一条数据                        ,用来处理适当的业务                        。(上面没有举例                ,自行验证)

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
js格式化时间格式(Javascript格式化工具)