Java中用Stream流取出分组后每组最大值对象的ID

取出分组后每组最大值对象的ID

如果只需要获取这些对象的ID(或其他特定字段),而不是整个对象,可以采用以下方法:

方法1:先获取对象再提取ID

java 复制代码
List<String> customerIds = orders.stream()
    .collect(Collectors.groupingBy(
        Order::getCustomerId,
        Collectors.maxBy(Comparator.comparing(Order::getOrderDate))
    ))
    .values().stream()
    .filter(Optional::isPresent)
    .map(Optional::get)
    .map(Order::getCustomerId) // 提取ID字段
    .collect(Collectors.toList());

方法2:直接在收集时提取ID(更高效)

java 复制代码
List<String> customerIds = orders.stream()
    .collect(Collectors.groupingBy(
        Order::getCustomerId,
        Collectors.collectingAndThen(
            Collectors.maxBy(Comparator.comparing(Order::getOrderDate)),
            opt -> opt.map(Order::getCustomerId).orElse(null)
        )
    ))
    .values().stream()
    .filter(Objects::nonNull)
    .collect(Collectors.toList());

方法3:使用toMap收集器(简洁版)

java 复制代码
List<String> customerIds = new ArrayList<>(
    orders.stream()
        .collect(Collectors.toMap(
            Order::getCustomerId,
            Function.identity(),
            (o1, o2) -> o1.getOrderDate().isAfter(o2.getOrderDate()) ? o1 : o2
        ))
        .values()
).stream()
.map(Order::getCustomerId)
.collect(Collectors.toList());

完整示例

java 复制代码
List<Order> orders = Arrays.asList(
    new Order("C1", LocalDate.of(2023, 1, 10), 100.0),
    new Order("C1", LocalDate.of(2023, 2, 15), 150.0),
    new Order("C2", LocalDate.of(2023, 1, 5), 200.0),
    new Order("C2", LocalDate.of(2023, 3, 20), 250.0),
    new Order("C3", LocalDate.of(2023, 2, 1), 300.0)
);

// 获取每个最新订单对应的客户ID
List<String> latestOrderCustomerIds = orders.stream()
    .collect(Collectors.groupingBy(
        Order::getCustomerId,
        Collectors.maxBy(Comparator.comparing(Order::getOrderDate))
    ))
    .values().stream()
    .flatMap(opt -> opt.map(Stream::of).orElseGet(Stream::empty))
    .map(Order::getCustomerId)
    .collect(Collectors.toList());

System.out.println("拥有最新订单的客户ID: " + latestOrderCustomerIds);

输出结果

复制代码
   拥有最新订单的客户ID: [C1, C2, C3]

关键点说明

  1. 如果只需要ID而不需要整个对象,建议使用方法2,它更高效
  2. map(Order::getCustomerId) 是提取ID的关键操作
  3. 方法3使用toMap合并函数,适合简单的最大/最小值场景
  4. 根据需求可以替换getCustomerId()为任何其他字段的getter方法
相关推荐
初听于你2 小时前
缓存技术揭秘
java·运维·服务器·开发语言·spring·缓存
小蒜学长3 小时前
springboot多功能智能手机阅读APP设计与实现(代码+数据库+LW)
java·spring boot·后端·智能手机
追逐时光者4 小时前
精选 4 款开源免费、美观实用的 MAUI UI 组件库,助力轻松构建美观且功能丰富的应用程序!
后端·.net
你的人类朋友5 小时前
【Docker】说说卷挂载与绑定挂载
后端·docker·容器
间彧5 小时前
在高并发场景下,如何平衡QPS和TPS的监控资源消耗?
后端
间彧5 小时前
QPS和TPS的区别,在实际项目中,如何准确测量和监控QPS和TPS?
后端
zizisuo5 小时前
解决在使用Lombok时maven install 找不到符号的问题
java·数据库·maven
间彧6 小时前
消息队列(RocketMQ、RabbitMQ、Kafka、ActiveMQ)对比与选型指南
后端·消息队列
笨蛋少年派6 小时前
JAVA基础语法
java·开发语言
Haooog6 小时前
654.最大二叉树(二叉树算法)
java·数据结构·算法·leetcode·二叉树