You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java 8中从对象列表获取各元素的最大数量项

问题描述

我有一个Item对象列表,Item类定义如下:

class Item {
  private String name;
  private int quantity;

  // 补充:流操作需要访问属性,必须添加getter方法
  public String getName() {
    return name;
  }

  public int getQuantity() {
    return quantity;
  }

  // 补充:用户代码中用到的构造方法
  public Item(String name, int quantity) {
    this.name = name;
    this.quantity = quantity;
  }
}

列表包含以下元素:

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));

我期望输出每个名称对应最大数量的Item列表,即包含Item("Item1", 15)、Item("Item2", 16)、Item("Item3", 10)、Item("Item4", 7)的列表。

我尝试了以下代码,但未得到正确结果:

List<Item> maxQuantityItems = itemList.stream()
            .filter(item -> item.getQuantity() == maxQuantity)
            .collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Item::getName))));

问题分析

你的代码存在两个核心问题:

  1. maxQuantity变量未定义,且逻辑错误:你要找的是每个名称下的最大数量,而非全局最大数量,直接过滤等于某个全局值的逻辑不成立
  2. 用TreeSet按名称去重的方式错误:TreeSet会仅保留每个名称的一个Item,但无法保证保留的是数量最大的那个

正确解决方案

要实现按名称分组并保留每组数量最大的Item,可通过Stream的分组+取最大值操作完成:

List<Item> maxQuantityItems = itemList.stream()
        // 按name分组,每组取quantity最大的Item
        .collect(Collectors.groupingBy(
                Item::getName,
                Collectors.maxBy(Comparator.comparingInt(Item::getQuantity))
        ))
        // 提取分组结果,过滤空值后转为列表
        .values().stream()
        .filter(Optional::isPresent)
        .map(Optional::get)
        .collect(Collectors.toList());

代码说明

  1. Collectors.groupingBy(Item::getName):将列表按name分组,得到Map<String, Optional<Item>>的中间结构
  2. Collectors.maxBy(Comparator.comparingInt(Item::getQuantity)):对每个分组内的Item,按quantity数值取最大值,返回Optional<Item>避免分组为空的异常
  3. 后续流操作提取Map中的所有分组结果,转为最终的列表

可选:保持结果顺序

如果需要结果顺序和原列表中名称首次出现的顺序一致,可指定用LinkedHashMap分组:

List<Item> maxQuantityItems = itemList.stream()
        .collect(Collectors.groupingBy(
                Item::getName,
                LinkedHashMap::new, // 用LinkedHashMap维持插入顺序
                Collectors.maxBy(Comparator.comparingInt(Item::getQuantity))
        ))
        .values().stream()
        .filter(Optional::isPresent)
        .map(Optional::get)
        .collect(Collectors.toList());

内容的提问来源于stack exchange,提问作者Rajib Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 22:32:49