1. Verificare

Cred că s-ar putea să te plictisești deja să înveți cum să înlănțuiești fluxurile de date. Vrei să faci în sfârșit ceva cu datele.

Clasa Streamare trei metode standard care nu construiesc fluxuri, ci verifică ce fel de date sunt în ele. Aceste metode sunt: anyMatch()​​, allMatch(), și noneMatch().

boolean anyMatch(rule)metodă

Această metodă verifică dacă fluxul are cel puțin un element care îndeplinește regula care este transmisă metodei. Dacă există un astfel de element, metoda returnează true, în caz contrar false.

Exemple

Cod Notă
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
boolean result = stream.anyMatch(x -> x > 0);

true
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.anyMatch(x -> x > 0);

true
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.filter(x -> x < 0).anyMatch(x -> x > 0);

false

În ultimul exemplu, reținem mai întâi doar elementele care sunt mai mici decât zero și apoi verificăm rezultatul pentru a vedea dacă oricare dintre elementele filtrate este mai mare decât zero. Desigur, astfel de elemente nu mai există.

metoda booleană allMatch (regulă).

Această metodă verifică dacă toate elementele din flux se potrivesc cu regula (cunoscută și ca predicat). Regula este transmisă ca argument la metoda:

Cod Notă
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
boolean result = stream.allMatch(x -> x > 0);
true
(toate elementele mai mari decât zero)
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.allMatch(x -> x > 0);
false
(există elemente mai mici sau egale cu zero?)
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.filter(x -> x < 0).allMatch(x -> x < 0);
true
(am reținut elementele care sunt mai mici decât zero)

În ultimul exemplu, permitem mai întâi doar elementele care sunt mai mici de zero să treacă prin filtru și apoi verificăm dacă toate elementele reținute sunt mai mici decât zero. Verificarea dă un rezultat pozitiv.

metoda booleană noneMatch(regulă).

Metoda noneMatch()verifică dacă fluxul nu are elemente care se potrivesc cu regula trecută. Este ca opusul metodei anyMatch().

Cod Notă
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
boolean result = stream.noneMatch(x -> x > 0);

false
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.noneMatch(x -> x > 0);

false
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.filter(x -> x < 0).noneMatch(x -> x > 0);

true


2. Clase de utilitate: Optionalclasa

Uneori este foarte incomod pentru programatori să lucreze cu nullreferințe. De exemplu, să presupunem că comparați două șiruri. Dacă ambele variabile nu sunt null, atunci puteți suna pur și simplu s1.equals(s2)și totul va funcționa. Dar dacă s1s-ar putea null, atunci trebuie să scrieți cod care se ocupă de această situație pentru a evita un NullPointerException.

De aceea, programatorii au venit cu Optional<T>clasa de utilitate. Codul său arată cam așa:

Cod Notă
class Optional<Type>
{
   private final Type value;
   private Optional() { this.value = null;}
   private Optional(value) { this.value = value;}
   public static <Type> Optional<Type> of(Type value)
   {
      return new Optional<Type>(value);
   }

   public boolean isPresent()
   {
      return value != null;
   }

   public boolean isEmpty()
   {
      return value == null;
   }

   public Type get()
   {
      if (value == null)
      {
         throw new NoSuchElementException();
      }
      return value;
   }

   public Type orElse(Type other)
   {
      return value != null ? value : other;
   }

   public Type orElseThrow()
   {
      if (value == null)
      {
         throw new NoSuchElementException();
      }
      return value;
   }
}










Verifică dacă valoarea nu este null



Verifică dacă valoarea este null




Returnează valoarea stocată. Aruncă o excepție dacă valoarea este nulă.







Returnează valoarea non-nulă stocată. Sau dacă valoarea stocată este null, atunci returnează valoarea transmisă ca argument al metodei



Returnează valoarea stocată non-nulă sau aruncă o excepție dacă valoarea este nulă.

Scopul acestei clase este pur și simplu de a stoca un obiect T (o referință la un obiect al cărui tip este T). Referința obiectului din interiorul unui Optional<T>obiect poate fi null.

Această clasă le permite programatorilor să scrie un cod puțin mai frumos. Să comparăm:

Utilizarea opțională Nu se utilizează Opțional
public void printString(String s)
{
   Optional<String> str = Optional.ofNullable(s);
   System.out.println(str.orElse(""));
}
public void printString(String s)
{
   String str = s != null ? s : "";
   System.out.println(str)
}

Un Optionalobiect poate fi întotdeauna comparat cu un alt Optionalobiect folosind equalsmetoda, chiar dacă stochează nullreferințe.

Pur și simplu vorbind, Optionalclasa vă permite să scrieți verificări „frumoase” nullși acțiuni „frumoase” în cazul în care un Optionalobiect stochează o nullvaloare.



3. Găsirea elementelor

Să ne întoarcem la Streamclasă. Clasa Streamare încă 4 metode care vă permit să căutați elemente într-un flux. Aceste metode sunt findFirst(), findAny(), min(), și max().

Optional<T> findFirst()metodă

Metoda findFirst()returnează pur și simplu primul element din flux. Asta e tot ce face.

Lucrul mai interesant de remarcat aici este că metoda nu returnează un Tobiect, ci mai degrabă un Optional<T>obiect wrapper. Acest lucru asigură că metoda nu va reveni niciodată nulldupă ce nu a găsit un obiect.

Exemplu:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String str = list.stream().findFirst().get(); // Hello

Pentru o mai mare clarificare, să împărțim ultima linie în mai multe rânduri:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");

Stream<String> stream = list.stream();
Optional<String> result = stream.findFirst();
String str = result.get(); // Hello

Ultima get()metodă este pur și simplu să recupereze valoarea stocată în interiorul obiectului Optional.

Optional<T> findAny()metodă

Metoda findAny()returnează orice element din flux și se termină acolo. Această metodă este similară cu findFirst(), dar este excelentă pentru fluxurile utilizate în operațiuni paralele.

Când procesați fluxuri în paralel, este posibil ca un element să fi fost deja găsit într-o parte a unui flux, dar nu este încă clar dacă este primul sau nu.

Dacă multe elemente s-au potrivit cu toate filtrele și este important ca programatorul să obțină exact primul dintre ele, atunci metoda findFirst()este cea care ar trebui să fie numită. Dacă programatorul știe că, în realitate, 0 sau 1 element se va potrivi cu toate filtrele, atunci este suficient să sune pur și simplu findAny()- și acest lucru va fi mai rapid.

Optional<T> min(Comparator<T>)metodă

Metoda min()folosește un comparatorobiect pentru a compara toate elementele din flux și returnează elementul minim. Cel mai convenabil mod de a defini un obiect comparator este cu o funcție lambda.

Exemplu de căutare a celui mai scurt șir:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String min = list.stream().min( (s1, s2)-> s1.length()-s2.length() ).get();

Optional<T> max(Comparator<T>)metodă

Metoda max()folosește un comparatorobiect pentru a compara toate elementele din flux și returnează elementul maxim. Cel mai convenabil mod de a defini un obiect comparator este cu o funcție lambda.

Exemplu de căutare a celui mai lung șir:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String max = list.stream().max( (s1, s2)-> s1.length()-s2.length() ).get();