问题出现
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