
本文介绍使用 java 8 stream api 和 collectors.tomap 实现按名称分组、保留各组最大 quantity 的 item 对象,高效生成去重后的“每类最高量”结果列表。
本文介绍使用 java 8 stream api 和 collectors.tomap 实现按名称分组、保留各组最大 quantity 的 item 对象,高效生成去重后的“每类最高量”结果列表。
在处理商品、库存或统计类业务数据时,常需对同名物品(如 "Item1")的多个记录取其最大数量项。原始列表中可能存在重复名称但不同 quantity 的 Item 对象,目标是:为每个唯一名称保留 quantity 最大的那一个实例,最终返回所有此类“局部最优”对象组成的列表。
核心思路是利用 Collectors.toMap 的三参数重载形式:
-
keyMapper:
Item::getName—— 以名称为键,实现自动去重; -
valueMapper:
Function.identity()—— 将Item对象本身作为值; -
mergeFunction:
(item1, item2) -> item1.getQuantity() >= item2.getQuantity() ? item1 : item2—— 当名称冲突时,保留 quantity 更大的那个。
完整示例代码如下:
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 "Item{name='" + name + "', quantity=" + quantity + "}";
}
}
// 使用示例
List<Item> itemList = Arrays.asList(
new Item("Item1", 5),
new Item("Item2", 10),
new Item("Item3", 10),
new Item("Item4", 7),
new Item("Item1", 15),
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{name='Item1', quantity=15},
// Item{name='Item2', quantity=16},
// Item{name='Item3', quantity=10},
// Item{name='Item4', quantity=7}]✅ 关键优势:
立即学习“Java免费学习笔记(深入)”;
- 单次流遍历完成分组与聚合,时间复杂度 O(n);
- 无需预先计算全局最大值,也无需嵌套循环或多次 stream 操作;
- 返回的是原始
Item对象(非新构造),保留全部字段完整性。
⚠️ 注意事项:
- 若
itemList为空,.values()返回空Collection,stream().collect(...)仍安全; -
toMap默认使用HashMap,不保证顺序;如需按插入顺序输出,可显式传入LinkedHashMap::new作为第四参数:.collect(Collectors.toMap( Item::getName, Function.identity(), (i1, i2) -> i1.getQuantity() >= i2.getQuantity() ? i1 : i2, LinkedHashMap::new // 保持首次出现顺序(或按需排序) )) - 若需最终结果按名称排序,可在
.values()后添加.stream().sorted(Comparator.comparing(Item::getName))。
该方案简洁、健壮且符合函数式编程思想,是 Java 8 处理“分组取极值”场景的标准实践。


















