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

Java中如何使用Stream流对CSV文件按日期时间字段排序

解决方案

完全可以通过Stream流实现按日期时间排序的需求,你只需要在现有过滤逻辑之后增加排序步骤即可,另外你的代码里还有两处需要先修正的问题:

  • 日期格式定义错误:你示例的日期分隔符是.,但你写的SimpleDateFormat模式用了/,且24小时制时间需要用HH而非12小时制的hh,同时YYYY代表周年,常规年份应该用yyyy。另外SimpleDateFormat是线程不安全的,更推荐用Java 8及以上版本提供的DateTimeFormatter。
  • 流关闭方式不推荐:手动调用close()容易在出现异常时无法正常关闭流,建议用try-with-resources语法自动管理流的关闭。

完整可运行代码(Java 8+通用版)

推荐先把每行数据封装成实体类再排序,避免排序过程中重复解析日期损耗性能:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.stream.Stream;

public class Logfilereader {
    // 定义和你日期格式匹配的格式化器,线程安全可全局复用
    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss");

    // 自定义实体类存储每行CSV数据,Java 16+可以直接用record更简洁
    static class CsvLine {
        LocalDateTime datetime;
        int seq;
        String type;
        String value;
        String unit;

        public CsvLine(LocalDateTime datetime, int seq, String type, String value, String unit) {
            this.datetime = datetime;
            this.seq = seq;
            this.type = type;
            this.value = value;
            this.unit = unit;
        }
    }

    public static void main(String[] args) throws IOException {
        // try-with-resources自动关闭流,不需要手动close
        try (Stream<String> rows1 = Files.lines(Path.of("C:\\Users\\julit\\IdeaProjects\\Logfilereader\\src\\testdata1.csv"))) {
            rows1
                    .map(x -> x.split(";"))
                    .filter(x -> x.length == 5)
                    .filter(x -> Integer.parseInt(x[1]) >= 0)
                    .filter(x -> "HYGRO".equals(x[2]) || "TEMP".equals(x[2]))
                    .filter(x -> "CELSIUS".equals(x[4]) || "PERCENT".equals(x[4]))
                    // 把数组转成实体类,提前解析好日期避免排序时重复解析
                    .map(arr -> new CsvLine(
                            LocalDateTime.parse(arr[0], DATE_TIME_FORMATTER),
                            Integer.parseInt(arr[1]),
                            arr[2],
                            arr[3],
                            arr[4]
                    ))
                    // 按日期时间升序排序,要降序的话加.reversed()即可
                    .sorted((o1, o2) -> o1.datetime.compareTo(o2.datetime))
                    // 输出结果
                    .forEach(line -> System.out.printf("%s %s %s %s %s%n",
                            line.datetime.format(DATE_TIME_FORMATTER),
                            line.seq,
                            line.type,
                            line.value,
                            line.unit
                    ));
        }
    }
}

小文件轻量实现方案(无需定义实体类)

如果你的CSV文件体积很小,不想额外定义实体类,也可以直接在排序阶段实时解析日期,缺点是排序过程中会重复解析日期,性能较差:

// 省略前面相同的过滤逻辑,直接替换sorted和后续输出部分即可
.sorted((arr1, arr2) -> {
    LocalDateTime time1 = LocalDateTime.parse(arr1[0], DATE_TIME_FORMATTER);
    LocalDateTime time2 = LocalDateTime.parse(arr2[0], DATE_TIME_FORMATTER);
    return time1.compareTo(time2);
})
.forEach(x -> System.out.println(x[0]+ " "+x[1]+" " +x[2]+ " "+x[3]+ " "+ x[4]));

内容的提问来源于stack exchange,提问作者Julius Tscherch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 22:06:03