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

如何通过Stream将文件属性合并为单一映射而非三个独立Map?

解决方案:用Stream一次性收集文件属性到单一映射

当然可以!你目前三次遍历文件集合的做法确实不够高效,完全可以通过一次Stream操作就把文件的名称、大小和最后修改时间收集到一个单一的映射结构中,无需自定义类(不过后面也会补充一个轻量的替代方案)。

核心思路

不再分别创建三个独立的Map,而是在一次文件遍历中,为每个File对象构建一个包含所有属性的内部Map,最终收集成Map<File, Map<String, Object>>(键是文件对象,值是封装了三个属性的Map)。这样既减少了文件系统的遍历次数,也实现了你想要的单一映射结构。

改造后的完整代码

RegexFileFilter fileFilter;
if (exe.equals("*")) {
    fileFilter = new RegexFileFilter(".*\\..*");
} else {
    fileFilter = new RegexFileFilter("\\." + exe);
}

// 一次性收集所有文件属性到单一ObservableMap中
ObservableMap<File, Map<String, Object>> fileInfoMap = FXCollections.observableMap(
    FileUtils.listFiles(targetDir, fileFilter, FileFileFilter.FILE)
        .stream()
        .collect(Collectors.toMap(
            Function.identity(), // 键为File对象本身
            file -> {
                // 为每个文件构建包含所有属性的内部Map
                Map<String, Object> fileProperties = new HashMap<>();
                fileProperties.put("name", file.getName());
                fileProperties.put("size", FileUtils.sizeOf(file));
                fileProperties.put("time", file.lastModified());
                return fileProperties;
            }
        ))
);

优化细节补充

  1. 简化内部Map的创建(Java 9+):如果你的Java版本在9及以上,可以用Map.of()来创建不可变的内部Map,代码更简洁:
file -> Map.of(
    "name", file.getName(),
    "size", FileUtils.sizeOf(file),
    "time", file.lastModified()
)

注意Map.of()创建的是不可变Map,如果后续需要修改属性,还是用HashMap更合适。

  1. 类型安全的轻量替代(Java 16+):虽然你提到不想用自定义类,但Java 16引入的Record是非常轻量的“数据载体”,几乎不需要额外代码,却能提供比Map更好的类型安全性。如果可以接受这种轻量类型,代码会更清晰:
// 定义一个仅包含数据的Record(无需额外方法)
record FileInfo(String name, long size, long lastModified) {}

// 收集时直接使用Record
ObservableMap<File, FileInfo> fileInfoMap = FXCollections.observableMap(
    FileUtils.listFiles(targetDir, fileFilter, FileFileFilter.FILE)
        .stream()
        .collect(Collectors.toMap(
            Function.identity(),
            file -> new FileInfo(file.getName(), FileUtils.sizeOf(file), file.lastModified())
        ))
);

这种方式既满足了“单一映射”的需求,又避免了Map的类型模糊问题,算是个折中的好方案。

为什么比原代码更好

原代码三次调用FileUtils.listFiles并遍历,相当于三次扫描目标目录;改造后的代码只遍历一次,大大提升了效率,尤其是在目录文件较多的情况下。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 08:17:39