【问题标题】:Dynamic filter chaining Java 8动态过滤器链接 Java 8
【发布时间】:2016-03-26 01:09:15
【问题描述】:

我有一个类似的代码

private void processFiles() {
        try {
            Files.walk(Paths.get(Configurations.SOURCE_PATH))
                    .filter(new NoDestinationPathFilter()) //<--This one
                    .filter(new NoMetaFilesOrDirectories()) //<--and this too
                    .forEach(
                            path -> {
                                new FileProcessorFactory().getFileProcessor(
                                        path).process(path);
                            });
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }

到目前为止,我还有其他各种方法,与上述方法相同,只是过滤器不同。有些方法有额外的过滤器,有些不同或没有。

是否有可能,我创建一个条件所需的过滤器集合并动态传递。并且集合中的所有过滤器都应用于流。我不想硬编码正在应用的过滤器列表。 我想让它基于配置。 我如何做到这一点?

【问题讨论】:

标签: java java-8


【解决方案1】:

你可以使用Files.find():

private void processFiles(final Path baseDir, final Consumer<? super Path> consumer,
    final Collection<BiPredicate<Path, BasicFileAttributes>> filters)
    throws IOException
{
    final BiPredicate<Path, BasicFileAttributes> filter = filters.stream()
        .reduce((t, u) -> true, BiPredicate::and);

    try (
        final Stream<Path> stream = Files.find(baseDir, Integer.MAX_VALUE, filter);
    ) {
        stream.forEach(consumer);
    }
}

是的,这意味着转换您的过滤器...

另见BiPredicateBasicFileAttributes的javadoc;特别是,BiPredicate 有一个 .and() 方法,您会发现它在您的情况下很有用。

【讨论】:

  • 我想这对我没有帮助。代码结构将从 .filter 更改为 .and 但仍将保留在代码中。我想让它基于配置
  • 您没有告诉任何有关基于配置的信息...此外,请注意,与您不同的是,我正确关闭了流。
【解决方案2】:

这个怎么样?

private void processFiles(List<Predicate<Path>> filterList) {
    Predicate<Path> compositeFilter=filterList.stream().reduce(w -> true, Predicate::and);
    try {
        Files.walk(Paths.get(Configurations.SOURCE_PATH))
             .filter(compositeFilter)
             .forEach(path -> {
                        new FileProcessorFactory().getFileProcessor(
                                path).process(path);
                    });

    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
}

【讨论】:

  • 请注意,这里不需要将 lambda 表达式写成语句。而不是path -&gt; { new FileProcessorFactory().getFileProcessor(path).process(path); },你可以简单地写path -&gt; new FileProcessorFactory().getFileProcessor(path).process(path)...
猜你喜欢
  • 1970-01-01
  • 2014-05-15
  • 1970-01-01
  • 2017-02-10
  • 1970-01-01
  • 2015-04-20
  • 2018-12-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多