解决java8 stream流操作Collectors.toMap()合并集合数组后,元素顺序改变的问题。

问题出现

java8提供了流式操作,我们可以用Collectors.toMap()方法,将两个相同长度的集合或者数组组合成一个map,示例代码如下:

String[] keys = ["key1","key2","key3","key4","key5"];
String[] values = ["value1","value2","value3","value4","value5"];
Map<String,String> valueMap = new LinkedHashMap<>();
valueMap = IntStream.range(0, keys.length).boxed()
           .collect(Collectors.toMap(j -> keys[j], j -> values[j]));

我期望的组合后的map中,键值对的顺序是和两个数组一致的,也就是key1和value1在第一个,生成的map的第一个也键值对也是key1:value1

所以我在创建map的时候,使用LinkedHashMap,以为这样可以使返回结果也是有序的,但返回结果仍然是无序的。

点开Collectors.toMap方法后,一起来看一下源码:

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

发现有HashMap::new字段指定的返回map的类型,用LinkedHashMap接收是没用的,我们查找toMap的其他重写方法,发现如下方法:

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

这里主要看方法的最后一个参数:Supplier< M > mapSupplier,方法注释上写道:

@param mapSupplier a function which returns a new, empty {@code Map} into which the results will be inserted

意思就是返回一个新的空map,结果将插入其中,而这个参数就是我们传入的map类型。

问题解决

知道了此方法,我们将原先代码修改为:

String[] keys = ["key1","key2","key3","key4","key5"];
String[] values = ["value1","value2","value3","value4","value5"];
Map<String,String> valueMap = new LinkedHashMap<>();
valueMap = IntStream.range(0, keys.length).boxed()
           .collect(Collectors.toMap(j -> keys[j], j -> values[j],(k1, k2) -> k1,LinkedHashMap::new));

第三个参数(k1, k2) -> k1表示出现相同的key时,取旧key值对应的value值。最后一个参数填入LinkedHashMap::new,指定返回新的map类型为LinkedHashMap。

创作不易,如果有帮到你的话,不妨点个赞呗~

参考:https://blog.csdn.net/qq_38252499/article/details/109528780

  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值