Java实现从Excel多条目列表中筛选用户最小/最大Date/Time
嘿,看起来你已经在处理Excel数据聚合的路上走了一段了!要把每个用户(按ID + fullname分组)的最早和最晚时间提取出来,其实可以通过分组聚合的方式简化代码,不用分别维护最大、最小日期的列表,一次性处理会更高效。下面给你具体的实现思路和代码示例:
核心处理思路
- 以
ID + fullname作为唯一标识对所有Excel记录分组 - 针对每个分组,直接计算
Date/Time字段的最小值和最大值 - 将分组后的结果整理为你需要的
ID、fullname、Max、Min结构列表
代码实现示例(基于Apache POI)
先假设你已经把Excel行数据读取到了自定义的实体类列表中,我们用Java Stream API来完成聚合:
// 定义对应Excel行的实体类 class ExcelRecord { private String id; private String fullname; private LocalDateTime dateTime; private String state; // 构造器、getter、setter方法按需实现 } // 定义最终输出的结果实体类 class UserTimeSummary { private String id; private String fullname; private LocalDateTime maxDateTime; private LocalDateTime minDateTime; public UserTimeSummary(String id, String fullname, LocalDateTime max, LocalDateTime min) { this.id = id; this.fullname = fullname; this.maxDateTime = max; this.minDateTime = min; } // getter、toString方法按需实现 } public class ExcelProcessor { public static void main(String[] args) { // 替换为你实际读取Excel数据的逻辑 List<ExcelRecord> rawRecords = readExcelFromFile(); // 分组聚合核心逻辑 List<UserTimeSummary> finalSummary = rawRecords.stream() // 用ID+fullname拼接作为分组键(也可以用Pair类避免字符串拼接冲突) .collect(Collectors.groupingBy(record -> record.getId() + "_" + record.getFullname())) .entrySet().stream() .map(entry -> { List<ExcelRecord> groupRecords = entry.getValue(); // 计算分组内的最小时间 LocalDateTime minTime = groupRecords.stream() .map(ExcelRecord::getDateTime) .min(LocalDateTime::compareTo) .orElse(null); // 计算分组内的最大时间 LocalDateTime maxTime = groupRecords.stream() .map(ExcelRecord::getDateTime) .max(LocalDateTime::compareTo) .orElse(null); ExcelRecord firstRecord = groupRecords.get(0); return new UserTimeSummary(firstRecord.getId(), firstRecord.getFullname(), maxTime, minTime); }) .collect(Collectors.toList()); // 替换为你实际写入结果到Excel的逻辑 writeSummaryToExcel(finalSummary); } // 模拟Excel读取方法 private static List<ExcelRecord> readExcelFromFile() { return new ArrayList<>(); } // 模拟结果写入方法 private static void writeSummaryToExcel(List<UserTimeSummary> summaryList) { // 实现写入逻辑 } }
针对你现有代码的优化方案
如果你已经分别维护了最大、最小日期的列表,可以通过Map快速合并两个列表的结果:
// 假设你已有的最大日期记录列表 List<MaxDateRecord> maxDateList = getMaxDateRecords(); // 假设你已有的最小日期记录列表 List<MinDateRecord> minDateList = getMinDateRecords(); // 将最小日期列表转为Map,方便快速查找 Map<String, LocalDateTime> minDateMap = minDateList.stream() .collect(Collectors.toMap( record -> record.getId() + "_" + record.getFullname(), MinDateRecord::getDateTime )); // 合并两个列表生成最终结果 List<UserTimeSummary> finalResult = maxDateList.stream() .map(record -> new UserTimeSummary( record.getId(), record.getFullname(), record.getDateTime(), minDateMap.get(record.getId() + "_" + record.getFullname()) )) .collect(Collectors.toList());
注意事项
- 如果
ID或fullname中包含下划线,建议用AbstractMap.SimpleEntry<String, String>作为分组键,避免字符串拼接冲突 - 处理超大Excel文件时,建议用EasyExcel这类流式读取库,避免内存溢出
内容的提问来源于stack exchange,提问作者NitKrish
相关产品推荐
相关产品推荐

