JAVA8: stream中Collections.toMap()

查看源码会发现toMap()有三个方法:图方便我标记为①②③
参数分别是2个,3个,4个。
在这里插入图片描述
第一个方法示例:
将一个list对象 处理成一个 map

Map<Integer, String> map = list.stream()
.collect(Collectors.toMap(Person::getId, Person::getName));

一般情况下是没有问题的,但是当list中存在重复对象时,就有问题了,以下为①源码:

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);
}
 
 
private static <T> BinaryOperator<T> throwingMerger() {
    return (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); };
}

可以看到①tomap方法调用的是③tomap方法,第三个参数是一个函数,第四个是放入的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);
    }

其中有个merge()方法,如果有key重复,就按照函数方法走,那么①tomap方法只有两参数,函数方法是源码定的,就是throwingMerger(),这段代码就是抛个异常。

所以。。。。。用Collectors.toMap()的第一个方法处理重复值的时候会抛异常

那怎么处理呢,就是将遇到重复值时的换一个函数处理。②方法就派上用场了。

Map<Integer, String> map = list.stream()
.collect(Collectors.toMap(Person::getId, Person::getName,(oldValue, newValue) -> newValue));

如果遇上重复值,使用新的value进行替换。

如果还需要排序输出就需要用上③方法,放到指定类型LinkedHashMap中

Map<Integer, String> map = list.stream().sorted(Map.Entry.comparingByKey())
.collect(Collectors.toMap(Person::getId, Person::getName,(oldValue, newValue) -> newValue),LinkedHashMap::New);

阐述的不是很完善,自己通过代码能够更全面的了解!

你可能感兴趣的:(java基础,java)