Я просматриваю код, который использует Predicate
в Java. Я никогда не использовал Predicate
. Может ли кто-нибудь направить меня к какому-либо учебнику или концептуальному объяснению Predicate
и его реализации в Java?
Предикат в Java
Ответы (4)
Я предполагаю, что вы говорите о com.google.common.base.Predicate<T>
из Гуавы.
Из API:
Определяет значение
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-ссылки
Iterables.filter
- Returns the elements that satisfy a predicate.
О функции высшего порядка
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
определен, и вместо него вы передаете объекты, реализующие этот интерфейс.
Смотрите также
Predicate<Integer>
, когда у нас уже есть F<Integer, Boolean>
, который делает то же самое?
- person Pacerier; 14.08.2014
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); Predicate<Integer> isEven = integer -> (integer % 2) == 0; Iterable<Integer> evenNumbers = numbers.stream().filter(isEven).collect(Collectors.toList());
- person ; 19.02.2018
Предикат — это функция, которая возвращает истинное/ложное (т.е. логическое) значение, в отличие от предложения, которое является истинным/ложным (т.е. логическим) значением. В Java не может быть автономных функций, поэтому предикат создается путем создания интерфейса для объекта, представляющего предикат, а затем предоставляется класс, реализующий этот интерфейс. Примером интерфейса для предиката может быть:
public interface Predicate<ARGTYPE>
{
public boolean evaluate(ARGTYPE arg);
}
И тогда у вас может быть такая реализация, как:
public class Tautology<E> implements Predicate<E>
{
public boolean evaluate(E arg){
return true;
}
}
Чтобы получить лучшее концептуальное понимание, вы можете прочитать о логике первого порядка.
Изменить
Существует стандартная ссылка Предикат интерфейса (java.util.function.Predicate), определенный в Java API начиная с Java 8. До Java 8 вам может быть удобно повторно использовать com.google.common.base.Predicate из Гуава.
Также обратите внимание, что в Java 8 намного проще писать предикаты с использованием лямбда-выражений. Например, в Java 8 и выше можно передать p -> true
функции вместо определения именованного подкласса тавтологии, как описано выше.
Вы можете просмотреть документ по Java примеры или пример использования Predicate здесь
В основном он используется для фильтрации строк в наборе результатов на основе любых конкретных критериев, которые могут у вас быть, и возвращает true для тех строк, которые соответствуют вашим критериям:
// the age column to be between 7 and 10
AgeFilter filter = new AgeFilter(7, 10, 3);
// set the filter.
resultset.beforeFirst();
resultset.setFilter(filter);
В дополнение к тому, что сказал Micheal:
Вы можете использовать Predicate следующим образом для фильтрации коллекций в java:
public static <T> Collection<T> filter(final Collection<T> target,
final Predicate<T> predicate) {
final Collection<T> result = new ArrayList<T>();
for (final T element : target) {
if (predicate.apply(element)) {
result.add(element);
}
}
return result;
}
один из возможных предикатов может быть:
final Predicate<DisplayFieldDto> filterCriteria =
new Predicate<DisplayFieldDto>() {
public boolean apply(final DisplayFieldDto displayFieldDto) {
return displayFieldDto.isDisplay();
}
};
Применение:
final List<DisplayFieldDto> filteredList=
(List<DisplayFieldDto>)filter(displayFieldsList, filterCriteria);
Predicate
Гуавы? Что-то похожее? Что-то совсем другое? - person polygenelubricants   schedule 02.06.2010Predicate
- person Dan Gravell   schedule 02.06.2010