首页 > 解决方案 > Java 8 - 获取父目录和子目录列表的地图

问题描述

我有一个这样的文件夹结构:

/home/user/root/
                dir1/
                     subDir1/
                             pdf1.pdf
                             log1.log
                     subDir2/
                             somefile.txt
                     subDir3
                dir2/
                     subDir1
                     subDir4
                     subDir5
                abc.txt
                def.pdf
                xyz.log

等等

我的要求是给定输入路径“/home/user/root/”,得到Map<String, List<String>>如下:

key: dir1, value: [subDir1, subDir2, subDir3]
key: dir2, value: [subDir1, subDir4, subDir5]
...
...

也就是说,映射的键是给定输入下的第一级目录,然后每个键都有一个值,即第一级下的子目录列表。

我能够获得一级目录的列表:

private Set<String> listFilesUsingFileWalk(String rootDir, int depth) throws IOException {
        Path path = Paths.get(rootDir);
        try (Stream<Path> stream = Files.walk(path, depth)) {
            return stream
                    .filter(file -> Files.isDirectory(file) && !file.equals(path))
                    .map(Path::getFileName)
                    //.forEach(d -> System.out.println(d.getFileName()));
                    .map(Path::toString)
                    .collect(Collectors.toSet());
        }
    }

但无法获得所需的输出。我认为递归可能是一种解决方案,但不能从 Java 8 流的角度来考虑。

请问这个可以建议吗?

标签: collectionsjava-8java-stream

解决方案


我仍然不确定您的深度参数的用途。但看起来你正在寻找这样的东西:

private Map<String,List<String>> listFilesUsingFileWalk(String rootDir, int depth) throws IOException {
        Path path = Paths.get(rootDir);
        try (Stream<Path> stream = Files.walk(path, depth)) {
            return stream
                    .filter(file -> Files.isDirectory(file) && !file.equals(path))
                    .collect(Collectors.toMap(
                            (p) -> p.getFileName().toString(),
                            (p) -> Arrays.stream(p.toFile().listFiles()).filter(File::isDirectory).map(File::getName).collect(Collectors.toList())
                    ));
        }
}

或(不使用 File 类)

private Map<String,List<String>> listFilesUsingFileWalk(String rootDir, int depth) throws IOException {
        Path path = Paths.get(rootDir);
        try (Stream<Path> stream = Files.walk(path, depth)) {
            return stream
                    .filter(file -> Files.isDirectory(file) && !file.equals(path))
                    .collect(Collectors.toMap(
                            (p) -> p.getFileName().toString(),
                            (p) -> {
                                try {
                                    return Files.list(p).filter(Files::isDirectory).map(Path::getFileName).map(Path::toString).collect(Collectors.toList());
                                } catch (IOException e) {
                                    return Collections.emptyList();
                                }
                            }
                    ));
        }
}

推荐阅读