Я переглядаю код, який використовується Predicate
на Java. Я ніколи не використовував Predicate
. Хтось може мене направляти до будь-якого навчального чи концептуального пояснення Predicate
та його реалізації на Java?
Predicate
Я переглядаю код, який використовується Predicate
на Java. Я ніколи не використовував Predicate
. Хтось може мене направляти до будь-якого навчального чи концептуального пояснення Predicate
та його реалізації на Java?
Predicate
Відповіді:
Я припускаю, що ви говорите про com.google.common.base.Predicate<T>
Гуаву.
З API:
Визначає значення a
true
абоfalse
значення для заданого входу. Наприклад,RegexPredicate
може реалізовуватиPredicate<String>
та повертати true для будь-якого рядка, що відповідає його заданому регулярному вираженню.
По суті це абстракція OOP для 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);
}
Зауважте, що тепер цикл для кожного набагато простіший без if
тесту. Ми досягли більш високого рівня абстрагування, визначивши Iterable<Integer> evenNumbers
, filter
використовуючи -ing Predicate
.
Iterables.filter
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>
те саме?
Присудок - це функція, яка повертає значення true / false (тобто булеве), на відміну від пропозиції, яке є значення true / false (тобто булеве). У 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
до функції замість визначення названого підкласу Tautology, як описано вище.
Ви можете переглянути приклади java doc або приклад використання предиката тут
В основному він використовується для фільтрації рядків у наборі результатів на основі будь-яких конкретних критеріїв, які у вас є, і повернення правдивих для тих рядків, які відповідають вашим критеріям:
// the age column to be between 7 and 10
AgeFilter filter = new AgeFilter(7, 10, 3);
// set the filter.
resultset.beforeFirst();
resultset.setFilter(filter);
Доповнення до сказаного Мікелем :
Для фільтрації колекцій у 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
? Щось подібне? Щось ще цілком?