stream流list转map Collectors.toMap()去重
时间: 2025-06-14 11:44:40 浏览: 2
### 使用 `Collectors.toMap()` 实现去重
在 Java 中,`Stream` 接口提供了强大的功能来操作集合数据。其中,`Collectors.toMap()` 是一种常用的方法,用于将 `List` 转换为 `Map`。然而,在实际应用中可能会遇到键重复的问题。为了避免这种情况下的异常(如 `IllegalStateException`),可以通过指定一个合并函数来解决。
以下是完整的解决方案:
#### 处理键冲突的代码示例
```java
import java.util.*;
import java.util.stream.Collectors;
class User {
private String id;
private String name;
public User setId(String id) {
this.id = id;
return this;
}
public User setName(String name) {
this.name = name;
return this;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
}
public class Main {
public static void main(String[] args) {
List<User> list = Arrays.asList(
new User().setId("1").setName("张小"),
new User().setId("2").setName("李大"),
new User().setId("2").setName("小明")
);
// 使用 Collectors.toMap 并提供合并逻辑
Map<String, String> map = list.stream()
.collect(Collectors.toMap(
User::getId, // Key 映射函数
User::getName, // Value 映射函数
(existingValue, newValue) -> existingValue // 合并逻辑:保留旧值
));
System.out.println(map);
}
}
```
在这个例子中,当键发生冲突时,`(existingValue, newValue) -> existingValue` 定义了一个简单的合并策略——保留第一个出现的值[^3]。
#### 输出结果解释
假设输入列表如下:
```plaintext
[
{"id": "1", "name": "张小"},
{"id": "2", "name": "李大"},
{"id": "2", "name": "小明"}
]
```
执行上述代码后的输出将是:
```plaintext
{1=张小, 2=李大}
```
这里,“2”对应的名称发生了冲突,因此选择了第一次出现的 “李大”。
---
### 更复杂的合并逻辑
如果希望自定义更复杂的合并规则,可以修改 `(existingValue, newValue)` 函数的内容。例如,可以选择最新的值或者组合两个值。
#### 示例:选择最新值
```java
.collect(Collectors.toMap(
User::getId,
User::getName,
(existingValue, newValue) -> newValue // 合并逻辑:保留新值
));
```
在这种情况下,最终的结果将会是:
```plaintext
{1=张小, 2=小明}
```
#### 示例:拼接字符串
```java
.collect(Collectors.toMap(
User::getId,
User::getName,
(existingValue, newValue) -> existingValue + "," + newValue // 合并逻辑:拼接字符串
));
```
此时,对于重复的键,其值会被连接起来,形成一个新的字符串。例如:
```plaintext
{1=张小, 2=李大,小明}
```
---
### 总结
通过向 `Collectors.toMap()` 提供三个参数(键映射器、值映射器以及合并函数),可以在键冲突的情况下灵活地控制行为。这不仅能够避免程序崩溃,还能满足不同的业务需求[^5]。
---
阅读全文
相关推荐


















