Reputation: 32969
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
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
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
Reputation: 198481
Guava team member here.
This is how I'd do it. There isn't a better way.
Upvotes: 3