当我们使用Stream API进行去重时,我们利用了Java 8引入的新特性和集合操作函数。
首先,让我们逐步解释上面提到的代码片段:
List<Object> uniqueObjects = list.stream()
.collect(Collectors.toMap(Object::getPno, Function.identity(), (existing, replacement) -> existing))
.values()
.stream()
.collect(Collectors.toList());
### 步骤解释:
1. **转换为Stream**:
list.stream()
这将把 `list` 转换为一个流(Stream),以便我们可以利用流操作来处理集合中的元素。
2. **使用Collectors.toMap进行去重**:
.collect(Collectors.toMap(Object::getPno, Function.identity(), (existing, replacement) -> existing))
这部分代码使用 `Collectors.toMap` 收集器来创建一个 Map。其中:
Object::getPno` 是一个方法引用,表示用对象的 `getPno()` 方法的返回值作为键。
Function.identity()` 表示用对象自身作为值。
(existing, replacement) -> existing` 是一个合并函数,当出现重复的键时,决定保留哪个值。这里我们选择保留先出现的对象(即 `existing`)。
这样,通过 `Collectors.toMap`,我们把对象的 `pno` 作为键,对象本身作为值,从而在构建过程中自动进行了去重操作(对于相同的 `pno`,只会保留先出现的对象)。
3. **获取唯一对象的值集合**:
.values()
一旦我们通过 `toMap` 创建了一个唯一 `pno` 的映射,我们通过 `values()` 方法获取这些唯一对象的集合。
4. **转换为List**:
.stream()
.collect(Collectors.toList());
最后,我们将这些唯一的对象集合转换回一个列表,这个列表就是我们想要的包含唯一对象的 `uniqueObjects`。
### 合并函数 `(existing, replacement) -> existing` 解释:
在 `Collectors.toMap` 中,第三个参数 `(existing, replacement) -> existing` 是一个合并函数,用于解决在构建 Map 时出现键冲突的情况。具体解释如下:
- `existing`:表示当前已经存在于 Map 中的值,即之前已经存储的对象。
- `replacement`:表示新加入的要存储的值,即即将加入的对象。
当我们遇到相同的键(即相同的 `pno`)时,合并函数 `(existing, replacement) -> existing` 的作用是告诉Java如何处理这种冲突。在这里,我们选择保留 `existing`,即保留先出现的对象,而不是替换为新的对象。
这样,通过合适的使用 `Collectors.toMap` 收集器和合并函数,我们能够非常高效地从一个列表中去除重复对象。