1. Kontroll

Jeg tror du kanskje allerede er lei av å lære å lenke sammen datastrømmer. Du vil endelig gjøre noe med dataene.

Klassen Streamhar tre standardmetoder som ikke konstruerer strømmer, men i stedet sjekker hva slags data som er i dem. Disse metodene er: anyMatch(), allMatch(), og noneMatch().

boolean anyMatch(rule)metode

Denne metoden sjekker om strømmen har minst ett element som tilfredsstiller regelen som sendes til metoden. Hvis det er et slikt element, returnerer metoden true, ellers false.

Eksempler

Kode Merk
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

I det siste eksemplet beholder vi først bare elementene som er mindre enn null, og deretter sjekker vi resultatet for å se om noen av de filtrerte elementene er større enn null. Selvfølgelig er slike elementer ikke lenger der.

boolsk allMatch (regel) metode

Denne metoden sjekker om alle elementene i strømmen samsvarer med regelen (også kjent som et predikat). Regelen overføres som et argument til metoden:

Kode Merk
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
boolean result = stream.allMatch(x -> x > 0);
true
(alle elementer større enn null)
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.allMatch(x -> x > 0);
false
(er det elementer mindre enn eller lik null?)
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.filter(x -> x < 0).allMatch(x -> x < 0);
true
(vi beholdt elementene som er mindre enn null)

I det siste eksemplet lar vi først bare elementer som er mindre enn null passere gjennom filteret, og deretter sjekker vi om alle de beholdte elementene er mindre enn null. Sjekken gir et positivt resultat.

boolesk noneMatch (regel) metode

Metoden noneMatch()sjekker om strømmen ikke har noen elementer som samsvarer med den godkjente regelen. Det er som det motsatte av anyMatch()metoden.

Kode Merk
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. Bruksklasser: Optionalklasse

Noen ganger er det veldig upraktisk for programmerere å jobbe med nullreferanser. Anta for eksempel at du sammenligner to strenger. Hvis begge variablene ikke er null, kan du ganske enkelt ringe s1.equals(s2), og alt vil fungere. Men hvis s1det er mulig null, må du skrive kode som håndterer denne situasjonen for å unngå en NullPointerException.

Det er derfor programmerere kom opp med verktøyklassen Optional<T>. Koden ser omtrent slik ut:

Kode Merk
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;
   }
}










Sjekker om verdien ikke er null



Kontrollerer om verdien er null




Returnerer den lagrede verdien. Kaster et unntak hvis verdien er null.







Returnerer den lagrede verdien som ikke er null. Eller hvis den lagrede verdien er null, returnerer verdien som sendes inn som et metodeargument



Returnerer den lagrede ikke-nullverdien eller kaster et unntak hvis verdien er null.

Hensikten med denne klassen er ganske enkelt å lagre et T-objekt (en referanse til et objekt hvis type er T). Objektreferansen inne i et Optional<T>objekt kan være null.

Denne klassen lar programmerere skrive litt penere kode. La oss sammenligne:

Bruker valgfritt Bruker ikke valgfritt
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)
}

Ett Optionalobjekt kan alltid sammenlignes med et annet Optionalobjekt ved hjelp av equalsmetoden, selv om de lagrer nullreferanser.

Enkelt sagt Optionallar klassen deg skrive "vakre" sjekker for nullog "vakre" handlinger i tilfelle et Optionalobjekt lagrer en nullverdi.



3. Finne elementer

La oss gå tilbake til Streamklassen. Klassen Streamhar 4 flere metoder som lar deg søke etter elementer i en strøm. Disse metodene er findFirst(), findAny(), min(), og max().

Optional<T> findFirst()metode

Metoden findFirst()returnerer ganske enkelt det første elementet i strømmen. Det er alt det gjør.

Det mer interessante å merke seg her er at metoden ikke returnerer et Tobjekt, men snarere et Optional<T>wrapper-objekt. Dette sikrer at metoden aldri kommer tilbake nulletter å ikke finne et objekt.

Eksempel:

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

La oss dele opp den siste linjen i flere linjer for å gjøre det bedre:

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

Den siste get()metoden er ganske enkelt å hente verdien som er lagret inne i Optionalobjektet.

Optional<T> findAny()metode

Metoden findAny()returnerer et hvilket som helst element fra strømmen og slutter der. Denne metoden ligner på findFirst(), men den er flott for bekker som brukes i parallelle operasjoner.

Når man behandler strømmer parallelt, kan det være at et element allerede er funnet i en del av en strøm, men det er ennå ikke klart om det er det første eller ikke.

Hvis mange elementer har matchet alle filtrene, og det er viktig for programmereren å få nøyaktig det første av dem, så findFirst()er metoden det som skal kalles. Hvis programmereren vet at 0 eller 1 element i virkeligheten vil matche alle filtrene, er det nok å bare ringe findAny()- og dette vil være raskere.

Optional<T> min(Comparator<T>)metode

Metoden min()bruker et comparatorobjekt for å sammenligne alle elementene i strømmen og returnerer minimumselementet. Den mest praktiske måten å definere et komparatorobjekt på er med en lambda-funksjon.

Eksempel på søk etter den korteste strengen:

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>)metode

Metoden max()bruker et comparatorobjekt for å sammenligne alle elementene i strømmen og returnerer det maksimale elementet. Den mest praktiske måten å definere et komparatorobjekt på er med en lambda-funksjon.

Eksempel på søk etter den lengste strengen:

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();