У мене є колекція Predicates
, сказати List<Predicate<File>>
. Тоді у мене є сингл File
і мені потрібно отримати предикат (якщо такий є), який відповідає файлу. Я думав, що ми використовуємо Iterables.find()
але, звичайно, це бере Predicate
не значення для переходу в a Predicate
. Я думав про реалізацію наступного, але не знаю, чи існує механізм.
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);
}
};
}
Це дозволить мені зробити наступне:
private List<Predicate<File>> filters = ...;
@Nullable
Predicate<File> findMatching(File file){
return Iterables.find(filters, createInversePredicate(file), null);
}
Чи є кращий спосіб?
Відповіді:
3 для відповіді № 1Член команди гуави тут.
Ось як я це роблю. Немає кращого способу.
3 для відповіді № 2
Я хотів би уникнути складності створення "зворотного" предиката і просто використовувати імперативний код:
private List<Predicate<File>> filters = ...;
@Nullable
Predicate<File> findMatchingFilter(File file){
for (Predicate<File> filter : filters) {
if (filter.apply(file)) {
return filter;
}
}
return null;
}
Це більш просто, і наступний програміст не повинен займати 1 хвилину, щоб зрозуміти цей «зворотний» предикатний бізнес :)
0 для відповіді № 3
Користувачі Java 8 можуть зробити це:
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);
}
Тут я вважаю, що тільки один предикат буде відповідати файлу.
Ви також можете використовувати Optional<Predicate<File>>
замість @Nullable
в Java 8.