Collections.toMap()

本文深入解析了Java中Collectors.toMap的方法重载,包括默认行为和自定义合并策略。当遇到重复key时,不提供合并函数会抛出异常,而通过mergeFunction可以指定处理策略,如取第一个值。此外,对于null key的情况,可以通过添加filter避免异常。文章还提供了示例代码以说明如何避免这些问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用流(stream)操作时,很多场景会用到list.stream()…filter()…collect(Collectors.toMap())操作。
今天进入collections源码,看一下Collectors.toMap参数的含义。

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) {
        return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
    }

坑1

throwingMerger():遇到流中的重复key时,抛出异常,并打印key。(重复key抛异常)
默认new HashMap。




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

自定义重复key处理策略
例:list.stream().collect(Collectors.toMap(Student::getId, Student::getName, (v1, v2) -> v1));
即遇到重复key时,value取先来的v1
默认new HashMap。




上面这两个重载方法其实调用的就是下面的这个:

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

参数KeyMapper:返回key的method,ex:(Book::getId)
参数valueMapper:返回value的method,ex:(Book::getName)
参数mergeFunction:遇到重复key时,处理策略,ex((v1,v2) -> v1)
Supplier mapSupplier:返回map/list的method,(HashMap::new/ConcurrentHashMap::new)

坑2

看其他文章说的,key为null也会导致异常,可自己试试。

解决办法:增加filter,过滤null key

bookList.stream().filter(book-> StringUtils.isNotEmpty(book.getId()))
                .collect(Collectors.toMap(BookDTO::getId,book -> (book.getName()+book.getPrice())));
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值