În general, predicat înseamnă o declarație care determină dacă o valoare poate fi adevărată sau falsă. În programare, predicatele înseamnă funcții cu un singur argument care returnează o valoare booleană. Functional Interface Predicate a fost realizat în Java 8. „Functional” înseamnă că conține o singură metodă abstractă. Acceptă un argument și returnează un boolean. În Java, interfețele funcționale sunt utilizate pentru gestionarea expresiilor Lambda, a constructorilor și a referințelor de metodă. De obicei, Java 8 Predicate este folosit pentru a aplica un filtru pentru o colecție de obiecte. Să aruncăm o privire la principalele sale aplicații și metodele utilizate pe scară largă, precum și să rezolvăm unele probleme de practică.
De ce dezvoltatorii folosesc Predicate
Practic, dezvoltatorii pot folosi predicate pentru orice activitate care implică evaluarea elementelor pe baza unor criterii predefinite și returnarea unei valori booleene. Iată exemple de sarcini simple pe care dezvoltatorii le gestionează folosind predicate:- Filtrarea unui set de numere întregi.
- Sortarea listelor prin asigurarea faptului că datele sunt conforme cu mai multe condiții predefinite (de exemplu, organizarea unei game de articole prin stabilirea condițiilor de preț și greutate).
- Utilizarea pachetelor de utilitate în programarea concomitentă.
Sintaxa predicatelor în Java
java.util.function.Predicate a fost introdus în Java 8 ca o modalitate alternativă de a gestiona impresiile de evaluare în Lambda. Vederea standard a interfeței este Predicate<T> , unde T este un singur argument care returnează o valoare booleană. Predicatele Java au un test de metodă (abstract) funcțional (Obiect) care evaluează acest predicat pe un obiect dat.
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
Iată un exemplu de scriere a unui predicat simplu care filtrează numerele întregi pe baza condițiilor „mai mare decât”, „mai mică decât”.
// An example of a simple Java predicate
import java.util.function.Predicate;
public class PredicateExample {
public static void main(String[] args)
{
// Creating predicate
Predicate<Integer> lesserThan = i -> (i < 18);
// Calling Predicate method
System.out.println(lesserThan.test(10));
}
}
Rezultatul va fi adevărat deoarece 10 < 18. Încă un exemplu cu Predicate în filter() . Predicatul ajută la filtrarea tuturor adulților din lista de vârste.
import java.util.List;
import java.util.function.Predicate;
public class PredicateExample {
public static void main(String[] args) {
List<Integer> ages = List.of(17, 18, 19, 28, 18, 28, 46, 7, 8, 9, 21, 12);
NotLessThan18<Integer> isAdult = new NotLessThan18<>();
ages.stream().filter(isAdult).forEach(System.out::println);
}
}
class NotLessThan18<E> implements Predicate<Integer> {
@Override
public boolean test(Integer v) {
Integer ADULT = 18;
return v >= ADULT;
}
}
Ieșirea este:
18 19 28 18 28 46 21
Metode de predicat Java 8
Interfața predicate are o mână de metode.- testul boolean(T t) evaluează predicatul pe argumentul dat.
- implicit Predicat<T> și (Predicat<? super T> other) returnează un predicat care reprezintă un ȘI logic de scurtcircuitare al acestui predicat și al altuia.
- implicit Predicate<T> sau returnează un predicat compus care reprezintă un SAU logic de scurtcircuitare al acestui predicat și al altuia.
- default Predicate<T> negate() returnează un predicat care este opus acestui predicat din punct de vedere logic.
- default Predicate<T> isEqual(Object targetRef) returnează un rezultat al testării dacă două argumente sunt egale conform Objects.equals(Object, Object) .
test boolean (T t)
Aceasta este o metodă funcțională pentru predicate Java care evaluează dacă un argument dat satisface sau nu condiția unui predicat. Exemplu: aici creăm un predicat adult pentru toată lumea care are 18 ani sau mai mult. metoda test() primește o valoare întreagă și o verifică.
import java.util.function.Predicate;
public class PredicateTestTest {
public static void main(String[] args) {
Predicate<Integer> adult = i -> i >= 18;
System.out.println(adult.test(12));
System.out.println(adult.test(19));
System.out.println(adult.test(21));
}
}
Care va fi rezultatul pentru codul de mai sus? În primul caz, deoarece 12 este mai mic decât 18, va fi fals. În ceea ce privește al doilea și al treilea scenariu, condițiile sunt îndeplinite, astfel încât întoarcerea va fi adevărată.
fals adevărat adevărat
implicit Predicate.and()
Această metodă reprezintă operatorul „și”. De aceea, dacă unul dintre predicatele date nu respectă o condiție stabilită, altul nu va primi o evaluare. Exemplu: Să compunem predicate în Java, filtrănd toți oamenii care sunt deja adulți, dar mai tineri de 65 de ani, folosind și() . Să folosim predicate.add () și să scriem un predicat java cu lambda pentru aceste condiții: Dacă condiția este adevărată, aplicația va returna următoarea declarație:
import java.util.function.Predicate;
public class PredicateDemo {
public static void main(String[] args) {
Predicate<Integer> adultYet = i -> i >= 18;
Predicate<Integer> adultStill = i -> i < 65;
System.out.println(adultYet.and(adultStill).test(5));
System.out.println(adultYet.and(adultStill).test(38));
System.out.println(adultYet.and(adultStill).test(90));
}
}
Ieșirea este:
fals adevărat fals
implicit Predicate.or()
Metoda Predicate.or() reprezintă operatorul „SAU”. Aceasta înseamnă că condiția va rămâne adevărată chiar dacă unul dintre cele două predicate este adevărat și celălalt este fals. Exemplu: să evaluăm acum șirurile de caractere. Încercați să utilizați metoda SAU pentru a sorta toate expresiile care conțin subșirul „meu” sau „creion”.
import java.util.function.Predicate;
public class PredicateDemo2 {
public static void main(String[] args) {
Predicate<String> containsA = t -> t.contains("crayon");
Predicate<String> containsB = t -> t.contains("my");
System.out.println(containsA.or(containsB).test("here is my crayon"));
System.out.println(containsA.or(containsB).test("here is my pencil"));
System.out.println(containsA.or(containsB).test("here is John's crayon"));
System.out.println(containsA.or(containsB).test("here is John's pencil"));
}
}
Ieșirea este:
adevărat adevărat adevărat fals
implicit Predicat negate()
Metoda negate() este utilizată pentru a aduna toate valorile care nu respectă criteriile predefinite. Exemplu: dacă doriți să sortați prin clasa „Roșii” și să găsiți toate intrările care nu sunt „Roșii”, puteți scrie un predicat și puteți scana rapid întreaga secvență. Încercați să scrieți singur codul pentru acesta și verificați-l cu soluția după ce ați terminat.
import java.util.function.Predicate;
public class PredicateDemo3 {
public static void main(String[] args) {
Predicate<Integer> adult = i -> i >= 18;
System.out.println(adult.negate().test(7)); System.out.println(adult.negate().test(19))
}
}
Ieșirea este:
adevarat fals
static Predicate isEqual(Object targetRef)
Această metodă este foarte utilă dacă doriți să determinați dacă două obiecte sunt egale cu o valoare definită ca parametru al Objects.equals(). Această metodă este utilă în special dacă trebuie să comparați rezultate similare ale testării. Exemplu: să presupunem că comparați două cărucioare de pere și doriți să vă asigurați că ambele au fructe de o greutate și o culoare standard. În acest caz, static Predicate isEqual(Object targetRef) este exact metoda de care aveți nevoie. Să aruncăm o privire la modul în care isEqual verifică egalitatea a două șiruri de caractere:
import java.util.function.Predicate;
public class PredicateDemo2 {
public static void main(String[] args) {
Predicate<String> i = Predicate.isEqual("here is my crayon");
System.out.println(i.test("here is my pencil"));
System.out.println(i.test("here is my crayon"));
}
}
Dacă un obiect pe care îl analizați respectă condițiile standard, funcția va returna true. Ieșirea este:
fals adevarat
Java IntPredicate
Java IntPredicate este o interfață funcțională, așa că o puteți utiliza ca țintă de atribuire pentru o expresie lambda sau o referință de metodă. IntPredicate operează pe un număr întreg și returnează o valoare de predicat bazată pe o condiție. Cum ar fi Interfața Predicate, IntPredicate are și metode test() și () , negate() sau () . Iată un exemplu de IntPredicate. De asemenea, filtrează toți adulții (18 sau mai mulți) din matrice.
import java.util.Arrays;
import java.util.function.IntPredicate;
public class IntPredicateExample {
public static void main(String[] args) {
int[] ages = { 18, 28, 18, 46, 90, 45, 2, 3, 1, 5, 7, 21, 12 };
IntPredicate p = n -> n >= 18;
Arrays.stream(ages).filter(p).forEach(System.out::println);
}
}
Ieșirea este:
18 28 18 46 90 45 21
Scrierea predicatelor curate în Java
Predicatele Java sunt extrem de funcționale și distractiv de lucrat. Cu toate acestea, dacă nu sunteți conștient de modul în care expresiile lambda pe care le scrieți impactează codul, există riscul de a reduce mentenabilitatea codului cu predicate dezordonate. Iată câteva practici simple care vă vor ajuta să vă asigurați că interfețele dvs. funcționale sunt ușor de gestionat și citit.- Nu vă repetați — nu compuneți predicate cu Java cu valori, metode și condiții repetate de mai multe ori. În acest fel, îți pierzi timpul productiv și faci codul dezordonat.
- Separați predicatele de codul aplicației pentru a asigura testabilitatea. În afară de asta, creați un program de testare a unității de predicate și respectați-l.
- Folosiți modele de import și compoziție pentru a vă asigura că cursurile nu sunt umflate și rămân ușor de gestionat.
- Luați în considerare mutarea predicatelor Java în clase Helper - în acest fel, îmbunătățiți reutilizarea codului și facilitați întreținerea.
- Lizibilitate — ori de câte ori este posibil, preferați declarațiile cu o linie în detrimentul predicatelor complexe. Ar putea fi tentant să vă arătați înțelegerea interfețelor funcționale complexe. Cu toate acestea, când vine vorba de întreținere, mai puțin înseamnă mai mult.
GO TO FULL VERSION