简体   繁体   English

动态过滤器链接Java 8

[英]Dynamic filter chaining Java 8

I have a code like 我有一个类似的代码

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();
        }
    }

As of now I have various other methods, which are same as the above one, with only difference in the filters. 到目前为止,我还有其他各种方法,与上述方法相同,只是过滤器有所不同。 Some methods have additional filters, some have different or none. 有些方法带有其他过滤器,有些则不同或没有。

Is it possible, that I create a collection of filters required for a condition and pass in dynamically. 是否可以创建条件所需的过滤器集合并动态传递。 And all the filters in the collection are applied on the stream. 并将集合中的所有过滤器应用于流。 I do not want to hard-code the list of filters being applied. 我不想对应用的过滤器列表进行硬编码。 I want to make it configuration based. 我想使其基于配置。 How do I achieve that? 我该如何实现?

You can just use Files.find() : 您可以只使用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);
    }
}

Yes, this will mean converting your filters... 是的,这将意味着转换您的过滤器...

See also the javadoc of BiPredicate and BasicFileAttributes ; 另请参见BiPredicateBasicFileAttributes的javadoc; in particular, BiPredicate has a .and() method which you will find useful in your situation. 特别是BiPredicate具有.and()方法,您会在自己的情况下发现它很有用。

How about this? 这个怎么样?

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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM