Java8中stream()操作toMap()时Duplicate key问题解决

本文探讨了在使用Java 8 Stream进行toMap转换时遇到的DuplicateKey异常,通过实例解析了出现的原因,并提供了两种解决方案:替换策略和列表存储重复值。适合理解Stream API在映射操作中的异常处理技巧。

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

问题描述:

最近使用Java8中Steam()流进行tomap转换编程时,遇到以下错误

java.lang.IllegalStateException: Duplicate key bbb
	at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
	at java.util.HashMap.merge(HashMap.java:1253)
	at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
	at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)

原因分析:

正如错误提示中所说的那样,tomap时遇到了重复键的问题,这里举个例子并记录一下解决方法。

准备以下User对象集合 ,构造方法User(Long Id, String username)


List<User> userList = new ArrayList<>();
        userList.add(new User(1L, "aaa"));
        userList.add(new User(2L, "bbb"));
        userList.add(new User(3L, "ccc"));
        userList.add(new User(2L, "ddd"));
        userList.add(new User(3L, "eee"));

当进行普通toMap操作时,就会出现我们上面的报错提示


Map<Long, String> map = userList.stream()
            .collect(Collectors.toMap(User::getId, User::getUsername);

解决方案:

解决方式就在Java8提供的Collectors.toMap() 方法中,其第三个参数就是当出现 duplicate key的时候的处理方案

方案一: 出现重复时,取前面value的值,或者取后面放入的value值,则覆盖先前的value值

// 取后面的值,舍弃前面的值
Map<Long, String> map = userList.stream()
            .collect(Collectors.toMap(User::getId, User::getUsername, (v1, v2) -> v2));

// 取前面的值,舍弃后面的值
Map<Long, String> map = userList.stream()
            .collect(Collectors.toMap(User::getId, User::getUsername, (v1, v2) -> v1));

方案二: Map的value可以储存一个list,把重复key的值放入list,再存到value中


userList.stream().collect(Collectors.toMap(User::getId,
                e -> Arrays.asList(e.getUsername()),
                (List<String> oldList, List<String> newList) -> {
                    oldList.addAll(newList);
                    return oldList;
                }));
Java 的 MyBatis 中,`ON DUPLICATE KEY UPDATE` 是一种在数据库插入操作中处理重复键冲突的机制。它通常用于 MySQL 数据库中的插入语句。 当你想要向数据库表中插入一行数据,但是该行数据的主键或唯一索引与已存在的数据冲突,`ON DUPLICATE KEY UPDATE` 语句提供了一种解决方案。它允许你在冲突发生执行更新操作,而不是简单地抛出错误。 在 MyBatis 的 XML 映射文件中,你可以使用 `ON DUPLICATE KEY UPDATE` 语句来处理重复键冲突。以下是一个示例代码: ```xml <!-- your-mapper.xml --> <insert id="insertOrUpdate" parameterType="YourObject"> INSERT INTO your_table (column1, column2, ...) VALUES (#{property1}, #{property2}, ...) ON DUPLICATE KEY UPDATE column1 = #{property1}, column2 = #{property2}, ... </insert> ``` 在上述代码中,`INSERT INTO` 子句用于插入数据,`VALUES` 子句用于指定要插入的值。接下来的 `ON DUPLICATE KEY UPDATE` 子句用于指定在出现重复键冲突执行的更新操作。你可以通过列名和属性名的对应关系来更新相应的列。 需要注意的是,`ON DUPLICATE KEY UPDATE` 仅适用于具有唯一索引或主键约束的列。如果在插入没有重复键冲突,将会执行插入操作;如果有冲突,将会执行更新操作。 此外,`ON DUPLICATE KEY UPDATE` 语句在不同的数据库中可能有所不同,具体的语法和支持程度可能会有差异。请根据你所使用的数据库类型和版本进行相应的调整。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

bug 

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

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

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

打赏作者

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

抵扣说明:

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

余额充值