javaStream流toMap小坑

先来show一下报错信息:
java.lang.IllegalStateException: Duplicate key 13800138000 (attempted merging values BlackTelChannel(id=null, tel=13800138000, source=A, industry=null, createdAt=null, available=null) and BlackTelChannel(id=null, tel=13800138000, source=C, industry=null, createdAt=null, available=null))
刚开始还以为是数据库数据有唯一索引。后面才发现是lambda-stream流tomap搞得鬼。

分析:
Collectors.toMap有3个方法,

方法1:2个参数,

toMap(Function<? super T, ? extends K> keyMapper,
                                Function<? super T, ? extends U> valueMapper) 

方法2: 3个参数,

toMap(Function<? super T, ? extends K> keyMapper,
                                Function<? super T, ? extends U> valueMapper,
                                BinaryOperator<U> mergeFunction) 

方法3: 4个参数

toMap(Function<? super T, ? extends K> keyMapper,
                         Function<? super T, ? extends U> valueMapper,
                         BinaryOperator<U> mergeFunction,
                         Supplier<M> mapFactory)

[当你希望使用特定类型的 Map(比如 LinkedHashMap、ConcurrentHashMap 等),而不是默认的 HashMap,就可以通过这个参数指定:() -> new LinkedHashMap<>()]

我是使用了3个参数就解决了问题,代码如下:

package com.funmz.vos2gaid2black;

import lombok.Builder;
import lombok.Data;
import org.junit.jupiter.api.Test;

import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class ScheduleTaskTest {

    @Data
    @Builder
    public static class BlackTelChannel implements Serializable {
        @Serial
        private static final long serialVersionUID = -8297608645555174167L;
        private String tel;
        private String source;
    }


    @Test
    public void testDuplicateTelToMap() {
        // 准备测试数据
        List<BlackTelChannel> oldList = new ArrayList<>();
        oldList.add(BlackTelChannel.builder().tel("13800138000").source("A").build());
        oldList.add(BlackTelChannel.builder().tel("13800138000").source("C").build()); // 与第一条 tel 重复
        oldList.add(BlackTelChannel.builder().tel("13900000000").source("B").build());
        oldList.add(BlackTelChannel.builder().tel("13700000000").source("D").build());

        System.out.println("oldList:" + oldList);
        System.out.println("oldList:" + oldList.size());

        // 执行转换逻辑
        Map<String, BlackTelChannel> oldBlackMap = oldList.stream()
                .collect(Collectors.toMap(
                        BlackTelChannel::getTel,
                        Function.identity()
                        , (existing, replacement) -> existing // existing 保留第一个遇到的 key ,replacement:最后一个
                ));
        System.out.println("oldBlackMap = " + oldBlackMap);
        System.out.println("oldBlackMap = " + oldBlackMap.size());

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林发和

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值