
使用 java 8 stream 和 collectors.tomap,可高效实现按 item 名称分组、保留每组中 quantity 最大的元素,并返回去重后的结果列表。
使用 java 8 stream 和 collectors.tomap,可高效实现按 item 名称分组、保留每组中 quantity 最大的元素,并返回去重后的结果列表。
在处理具有重复名称但不同数量的物品列表时,常见需求是:对同名 item 合并去重,仅保留 quantity 最大的那一个实例。这本质上是一个“分组取极值”问题,而非简单筛选全局最大值。直接用 filter 配合预计算的 maxQuantity(如原代码所示)只能获取所有等于全局最大值的项,无法满足“每个名称取各自最大值”的要求。
正确解法是利用 Collectors.toMap 的三参数重载形式:
-
keyMapper:
Item::getName—— 以名称为键,确保同名 item 归入同一组; -
valueMapper:
Function.identity()—— 将 item 本身作为值; -
mergeFunction:
(item1, item2) -> item1.getQuantity() >= item2.getQuantity() ? item1 : item2—— 当键冲突(即名称重复)时,保留 quantity 更大的那个 item。
该方法天然支持流式处理与并发安全(若需并行,可替换为 Collectors.toConcurrentMap),且逻辑清晰、无副作用。
以下是完整可运行示例:
import java.util.*;
import java.util.stream.Collectors;
class Item {
private final String name;
private final int quantity;
public Item(String name, int quantity) {
this.name = name;
this.quantity = quantity;
}
public String getName() { return name; }
public int getQuantity() { return quantity; }
@Override
public String toString() {
return String.format("Item(\"%s\", %d)", name, quantity);
}
}
// 使用示例
public class MaxQuantityExample {
public static void main(String[] args) {
List<item> itemList = new ArrayList();
itemList.add(new Item("Item1", 5));
itemList.add(new Item("Item2", 10));
itemList.add(new Item("Item3", 10));
itemList.add(new Item("Item4", 7));
itemList.add(new Item("Item1", 15));
itemList.add(new Item("Item2", 16));
List<item> maxItems = itemList.stream()
.collect(Collectors.toMap(
Item::getName,
Function.identity(),
(item1, item2) -> item1.getQuantity() >= item2.getQuantity() ? item1 : item2
))
.values()
.stream()
.collect(Collectors.toList());
System.out.println(maxItems);
// 输出: [Item("Item1", 15), Item("Item2", 16), Item("Item3", 10), Item("Item4", 7)]
}
}</item></item>
⚠️ 注意事项:
-
toMap返回的是Map,调用.values()得到的是Collection,如需严格List类型,建议后续.stream().collect(Collectors.toList())显式转换; - 若原始列表可能含
null名称,需提前过滤(filter(Objects::nonNull)或filter(item -> item.getName() != null)),否则Item::getName会抛NullPointerException; - 该方案时间复杂度为 O(n),空间复杂度为 O(k)(k 为唯一名称数),优于嵌套循环或多次 stream 操作。
总结:Collectors.toMap 的合并函数机制,是解决“分组后聚合取优”类问题的标准、简洁且高性能的 Java 8 方案。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











