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
相关产品推荐
相关产品推荐

