John B
John B

Reputation: 32969

Find matching Predicate. Predicate of Predicate?

I have a collection of Predicates, say List<Predicate<File>>. I then have a single File and I need to get the predicate (if any) that matches the file. I was thinking along the lines of using Iterables.find() but of course that takes a Predicate not a value to pass into a Predicate. I thought about implementing the following but don't know if there already exists a mechanism.

public static <T> Predicate<Predicate<? super T>> createInversePredicate(
        final T value) {
    return new Predicate<Predicate<? super T>>() {

        @Override
        public boolean apply(Predicate<? super T> input) {
            return input.apply(value);
        }
    };
}

This would allow me to do the following:

private List<Predicate<File>> filters = ...;

@Nullable
Predicate<File> findMatching(File file){
    return Iterables.find(filters, createInversePredicate(file), null);
}

Is there a better way?

Upvotes: 2

Views: 1313

Answers (3)

partheinstein
partheinstein

Reputation: 109

Java 8 users can do this:

Predicate<File> findMatching(File file) {
  List<Predicate<File>> matchingFilters = filters.stream().filter(predicate -> predicate.test(file)).collect(Collectors.toList());
  return matchingFilters.isEmpty()? null : matchingFilters.get(0);
}

Here I am assuming only one predicate will match the file.

You can also use Optional<Predicate<File>> instead of @Nullable in Java 8.

Upvotes: 0

Etienne Neveu
Etienne Neveu

Reputation: 12692

I would avoid the complexity of creating an "inverse" predicate, and simply use imperative code:

private List<Predicate<File>> filters = ...;

@Nullable
Predicate<File> findMatchingFilter(File file){
    for (Predicate<File> filter : filters) {
        if (filter.apply(file)) {
            return filter;
        }
    }
    return null;
}

It's more straightforward, and the next programmer won't need to take 1 minute to understand this "inverse" predicate business :)

Upvotes: 3

Louis Wasserman
Louis Wasserman

Reputation: 198481

Guava team member here.

This is how I'd do it. There isn't a better way.

Upvotes: 3

Related Questions