Полагаю, вы говорите о com.google.common.base.Predicate<T>
из Гуавы.
Из API:
* +1007 *
Определяет значение true
или false
для данного входа. Например, RegexPredicate
может реализовывать Predicate<String>
и возвращать true для любой строки, которая соответствует заданному регулярному выражению.
Это, по сути, абстракция ООП для теста boolean
.
Например, у вас может быть вспомогательный метод, подобный этому:
static boolean isEven(int num) {
return (num % 2) == 0; // simple
}
Теперь, учитывая List<Integer>
, вы можете обрабатывать только четные числа, как это:
List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
for (int number : numbers) {
if (isEven(number)) {
process(number);
}
}
При Predicate
тест if
абстрагируется как тип. Это позволяет ему взаимодействовать с остальным API, таким как Iterables
, у которого есть много служебных методов, которые принимают Predicate
.
Таким образом, теперь вы можете написать что-то вроде этого:
Predicate<Integer> isEven = new Predicate<Integer>() {
@Override public boolean apply(Integer number) {
return (number % 2) == 0;
}
};
Iterable<Integer> evenNumbers = Iterables.filter(numbers, isEven);
for (int number : evenNumbers) {
process(number);
}
Обратите внимание, что теперь цикл for-each намного проще без теста if
. Мы достигли более высокого уровня абстракции, определив Iterable<Integer> evenNumbers
, filter
, используя Predicate
.
API ссылки
О функции высшего порядка
Predicate
позволяет Iterables.filter
служить в качестве так называемой функции высшего порядка. Само по себе это дает много преимуществ. Возьмите List<Integer> numbers
пример выше. Предположим, мы хотим проверить, все ли числа положительны. Мы можем написать что-то вроде этого:
static boolean isAllPositive(Iterable<Integer> numbers) {
for (Integer number : numbers) {
if (number < 0) {
return false;
}
}
return true;
}
//...
if (isAllPositive(numbers)) {
System.out.println("Yep!");
}
С Predicate
и взаимодействием с остальными библиотеками мы можем вместо этого написать:
Predicate<Integer> isPositive = new Predicate<Integer>() {
@Override public boolean apply(Integer number) {
return number > 0;
}
};
//...
if (Iterables.all(numbers, isPositive)) {
System.out.println("Yep!");
}
Надеюсь, теперь вы можете увидеть значение в более высоких абстракциях для таких подпрограмм, как «фильтровать все элементы по заданному предикату», «проверить, все ли элементы удовлетворяют данному предикату» и т. Д., Чтобы улучшить код.
К сожалению, в Java нет первоклассных методов: вы не можете передавать методы в Iterables.filter
и Iterables.all
. Конечно, вы можете передавать объектов в Java. Таким образом, тип Predicate
определен, и вы передаете объекты , реализующие этот интерфейс.
Смотри также