使用lambda的嵌套过滤器

时间:2018-03-06 18:51:25

标签: java lambda java-8 java-stream

我正在尝试编写多级过滤器。我有文件夹和文件。

public class Folder {
  String name;
  List<Folder> folders;
  List<File> files;
  ...
}

public class File {
  String name;
  String type;
  ...
}

我需要一个寻找某些属性的过滤器,例如name,可以是文件夹/文件名。我编写了一段适用于一个级别的代码,但我不知道如何才能找到两级循环。

最终结果将是一个文件夹列表:名称与“名称过滤器”匹配的文件夹列表。或文件名与过滤器匹配的文件夹。

List<Folder> result = folders.stream()
  .filter(folder -> folder.getFiles().stream().anyMatch(file -> file.getName().contains(filter)))
  .collect(Collectors.toList());

2 个答案:

答案 0 :(得分:3)

我认为最好在Folder类中添加一个帮助器方法,将嵌套文件夹递归地压缩为Stream:

class Folder {
    String name;
    List<Folder> folders;
    List<File> files;

    Stream<Folder> flatten() {
        return Stream.concat(Stream.of(this), folders.stream().flatMap(Folder::flatten));
    }
}

之后,您可以使用flatMap(...)

获取最终结果
List<Folder> result = folders.stream()
    .flatMap(Folder::flatten)
    .filter(folder -> folder.getFiles()
        .stream()
        .anyMatch(file -> file.getName().contains(filter)))
    .collect(Collectors.toList());

答案 1 :(得分:0)

运行测试,跨文件夹按文件名过滤(没有任何帮助方法)。

predicate方法中的filter与flatMap有所不同,因为@Ernest指的是将所有File元素展平为一个列表。

k

几乎与@Oleksandr建议的一致。

编辑:我发现错过了文件夹可以包含文件夹的事实。我应该删除这个答案吗?