原因分析: 

这个错误表明在使用Java Stream API的toMap方法时发生了重复的键值对冲突。具体来说,当使用toMap方法将流中的元素收集到一个Map中时,如果出现了重复的键,则会抛出IllegalStateException异常。

根本原因:
Map<String, String> map = new HashMap<>();
map.put("key1", "value1");
// 尝试再次添加相同的键
map.put("key1", "newValue");

// 运行这段代码将会抛出 java.lang.IllegalStateException 异常
// 因为在HashMap中,键是不允许重复的,第二次put操作会尝试替换原有的键值对,
// 但在ConcurrentHashMap或其他并发容器的部分操作中(比如computeIfAbsent在旧值不存在时才设置新值),如果在多线程环境下同时尝试插入相同的键,也可能抛出IllegalStateException。
 toMap操作时:

1.建一个userList,将id传入一个重复的


List lcsList = new ArrayList<>();
        lcsList.add(1);
        lcsList.add(2);
        lcsList.add(2);
        lcsList.add(3);

 2.将lcsList中id的数据查到,用toMap转换为Map

Map<String, String> map = Maps.newHashMap();
map = userService.list(new LambdaQueryWrapper<User>()
    .in(User::getId, lcsList)).stream()
    .collect(toMap(User::getId, User::getUsername);

这样两种方式就会出现我们上面的报错提示 

解决

可以使用在Java8提供的Collectors.toMap方法的第三个参数来指定出现重复键时的解决策略。

第一种方法: 
// 取后面的值覆盖前面的值
Map<String, String> map = Maps.newHashMap();
map = userService.list(new LambdaQueryWrapper<User>()
    .in(User::getId, lcsList)).stream()
    .collect(toMap(User::getId, User::getUsername, (v1, v2) -> v2));

// 取前面的值覆盖后面的值
Map<String, String> map = Maps.newHashMap();
map = userService.list(new LambdaQueryWrapper<User>()
    .in(User::getId, lcsList)).stream()
    .collect(toMap(User::getId, User::getUsername, (v1, v2) -> v1));
第二种方法:
Map<String, List<String>> map = new HashMap<>();

for (String phone : phoneList) {
    if (map.containsKey(phone)) {
        map.get(phone).add("重复的值");
    } else {
        List<String> list = new ArrayList<>();
        list.add("第一个值");
        map.put(phone, list);
    }
}
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐