1. Comprobación

Creo que es posible que ya esté aburrido de aprender a encadenar flujos de datos. Quiere finalmente hacer algo con los datos.

La Streamclase tiene tres métodos estándar que no construyen flujos, sino que verifican qué tipo de datos hay en ellos. Estos métodos son: anyMatch(), allMatch()y noneMatch().

boolean anyMatch(rule)método

Este método verifica si la transmisión tiene al menos un elemento que cumpla con la regla que se pasa al método. Si existe tal elemento, el método devuelve true, de lo contrario false.

Ejemplos

Código Nota
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

En el último ejemplo, primero retenemos solo los elementos que son menores que cero y luego verificamos el resultado para ver si alguno de los elementos filtrados es mayor que cero. Por supuesto, tales elementos ya no están allí.

método booleano allMatch (regla)

Este método comprueba si todos los elementos de la secuencia coinciden con la regla (también conocida como predicado). La regla se pasa como argumento al método:

Código Nota
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
boolean result = stream.allMatch(x -> x > 0);
true
(todos los elementos mayores que cero)
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.allMatch(x -> x > 0);
false
(¿hay elementos menores o iguales a cero?)
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.filter(x -> x < 0).allMatch(x -> x < 0);
true
(retenemos los elementos que son menores que cero)

En el último ejemplo, primero permitimos que solo los elementos que son menores que cero pasen por el filtro y luego verificamos si todos los elementos retenidos son menores que cero. El cheque arroja un resultado positivo.

método booleano noneMatch(regla)

El noneMatch()método verifica si la transmisión no tiene elementos que coincidan con la regla aprobada. Es como lo contrario del anyMatch()método.

Código Nota
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. Clases de utilidad: Optionalclase

A veces es muy inconveniente para los programadores trabajar con nullreferencias. Por ejemplo, suponga que está comparando dos cadenas. Si ambas variables no son null, simplemente puede llamar s1.equals(s2)y todo funcionará. Pero si s1pudiera ser null, entonces tienes que escribir un código que maneje esta situación para evitar un NullPointerException.

Es por eso que a los programadores se les ocurrió la Optional<T>clase de utilidad. Su código se ve más o menos así:

Código Nota
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;
   }
}










Comprueba si el valor no es null



Comprueba si el valor es null




Devuelve el valor almacenado. Lanza una excepción si el valor es nulo.







Devuelve el valor no nulo almacenado. O bien, si el valor almacenado es null, devuelve el valor pasado como argumento del método.



Devuelve el valor no nulo almacenado o lanza una excepción si el valor es nulo.

El propósito de esta clase es simplemente almacenar un objeto T (una referencia a un objeto cuyo tipo es T). La referencia de objeto dentro de un Optional<T>objeto puede ser null.

Esta clase permite a los programadores escribir un código un poco más bonito. Comparemos:

Usando Opcional No usar Opcional
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 Optionalobjeto siempre se puede comparar con otro Optionalobjeto utilizando el equalsmétodo, incluso si almacenan nullreferencias.

Simplemente hablando, la Optionalclase le permite escribir cheques "hermosos" nully acciones "hermosas" en el caso de que un Optionalobjeto almacene un nullvalor.



3. Encontrar elementos

Volvamos a la Streamclase. La Streamclase tiene 4 métodos más que le permiten buscar elementos en una secuencia. Estos métodos son findFirst(), findAny(), min()y max().

Optional<T> findFirst()método

El findFirst()método simplemente devuelve el primer elemento de la secuencia. Eso es todo lo que hace.

Lo más interesante a tener en cuenta aquí es que el método no devuelve un Tobjeto, sino un Optional<T>objeto contenedor. Esto asegura que el método nunca regresará nulldespués de no poder encontrar un objeto.

Ejemplo:

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

Para mayor claridad, dividamos la última línea en varias líneas:

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

El último get()método simplemente recupera el valor almacenado dentro del Optionalobjeto.

Optional<T> findAny()método

El findAny()método devuelve cualquier elemento de la secuencia y termina allí. Este método es similar a findFirst(), pero es ideal para flujos que se usan en operaciones paralelas.

Al procesar flujos en paralelo, es posible que ya se haya encontrado un elemento en alguna parte de un flujo, pero aún no está claro si es el primero o no.

Si muchos elementos han coincidido con todos los filtros, y es importante que el programador obtenga exactamente el primero de ellos, entonces findFirst()se debe llamar al método. Si el programador sabe que, en realidad, 0 o 1 elemento coincidirá con todos los filtros, entonces es suficiente simplemente llamar findAny(), y esto será más rápido.

Optional<T> min(Comparator<T>)método

El min()método utiliza un comparatorobjeto para comparar todos los elementos de la secuencia y devuelve el elemento mínimo. La forma más conveniente de definir un objeto comparador es con una función lambda.

Ejemplo de búsqueda de la cadena más corta:

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>)método

El max()método usa un comparatorobjeto para comparar todos los elementos en la secuencia y devuelve el elemento máximo. La forma más conveniente de definir un objeto comparador es con una función lambda.

Ejemplo de búsqueda de la cadena más larga:

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