简体   繁体   中英

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() :

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 ; in particular, BiPredicate has a .and() method which you will find useful in your situation.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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