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

Java List按日期分组并筛选每组currentSpeed最大值记录

问题描述

我有一个存储公交运行数据的List<HashMap<String, Object>>,数据结构示例如下:

[原数据JSON]

我需要按dataDateTime字段的日期部分(例如2022-08-27、2022-08-26)分组,每组只保留currentSpeed数值最大的那条记录,最终期望结果如下:

[期望结果JSON]

以下是初始化这个List的Java代码:

[原初始化Java代码]

我尝试用Stream处理时出现了"Not a statement"错误,错误代码如下:

[错误Stream代码]

请问有没有高效的实现方法?


高效实现方案

1. Stream正确实现(推荐)

先说明你出现Not a statement错误的常见原因:要么是Stream操作缺少终端方法(比如没写collect),要么是语法结构错误(比如Lambda写法不当、未将结果赋值给变量)。下面是符合规范的Stream实现,核心逻辑是按日期分组+每组筛选速度最大值记录:

import java.util.*;
import java.util.stream.Collectors;

public class BusDataHandler {
    public static void main(String[] args) {
        // 替换为你的List初始化代码
        List<HashMap<String, Object>> busDataList = [原初始化Java代码];

        // 分组并保留每组速度最大的记录
        Map<String, HashMap<String, Object>> dateToMaxSpeedMap = busDataList.stream()
                // 提取日期作为分组Key(假设dataDateTime格式为yyyy-MM-dd HH:mm:ss,截取前10位)
                .collect(Collectors.groupingBy(
                        item -> ((String) item.get("dataDateTime")).substring(0, 10),
                        // 每组筛选currentSpeed最大的记录
                        Collectors.collectingAndThen(
                                Collectors.maxBy(Comparator.comparingDouble(
                                        item -> Double.parseDouble(item.get("currentSpeed").toString())
                                )),
                                Optional::get
                        )
                ));

        // 转换为List格式(如果需要)
        List<HashMap<String, Object>> resultList = new ArrayList<>(dateToMaxSpeedMap.values());
        
        // 输出结果
        resultList.forEach(System.out::println);
    }
}

代码说明

  • 分组Key提取:如果你的dataDateTime格式不是yyyy-MM-dd HH:mm:ss,可以改用DateTimeFormatter解析日期,比如:
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    LocalDateTime dt = LocalDateTime.parse((String) item.get("dataDateTime"), formatter);
    return dt.toLocalDate().toString();
    
  • 最大值筛选:Collectors.maxBy返回Optional,通过collectingAndThen直接取出值(每组至少有一条数据,不会触发空指针)。
  • 性能:Stream分组基于哈希表实现,时间复杂度O(n),适合大规模数据处理。

2. 传统循环实现(易读性强)

如果对Stream不熟悉,用传统循环同样高效:

List<HashMap<String, Object>> busDataList = [原初始化Java代码];
Map<String, HashMap<String, Object>> dateToMaxSpeedMap = new HashMap<>();

for (HashMap<String, Object> item : busDataList) {
    String date = ((String) item.get("dataDateTime")).substring(0, 10);
    double currentSpeed = Double.parseDouble(item.get("currentSpeed").toString());

    HashMap<String, Object> existingItem = dateToMaxSpeedMap.get(date);
    if (existingItem == null) {
        dateToMaxSpeedMap.put(date, item);
    } else {
        double existingSpeed = Double.parseDouble(existingItem.get("currentSpeed").toString());
        if (currentSpeed > existingSpeed) {
            dateToMaxSpeedMap.put(date, item);
        }
    }
}

List<HashMap<String, Object>> resultList = new ArrayList<>(dateToMaxSpeedMap.values());

错误代码的常见修正点

如果你的错误代码类似busDataList.stream().groupingBy(...);,问题在于没有终端操作且未赋值——Stream中间操作必须配合终端操作(如collect)才能执行,且需要将结果赋值给变量,否则会被编译器判定为无效语句。

内容的提问来源于stack exchange,提问作者Emmanuel Njorodongo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 11:15:42