Saltar al contenido

¿Cómo comprobar si un flujo de Java 8 está vacío?

Te damos la bienvenida a nuestra página web, aquí hallarás la respuesta de lo que andabas buscando.

Solución:

Esto puede ser suficiente en muchos casos.

stream.findAny().isPresent()

Las otras respuestas y comentarios son correctos en el sentido de que para examinar el contenido de una transmisión, se debe agregar una operación de terminal, por lo que “consume” la transmisión. Sin embargo, se puede hacer esto y volver a convertir el resultado en una secuencia, sin almacenar en búfer todo el contenido de la secuencia. Aqui hay un par de ejemplos:

static  Stream throwIfEmpty(Stream stream) 
    Iterator iterator = stream.iterator();
    if (iterator.hasNext()) 
        return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false);
     else 
        throw new NoSuchElementException("empty stream");
    


static  Stream defaultIfEmpty(Stream stream, Supplier supplier) 
    Iterator iterator = stream.iterator();
    if (iterator.hasNext()) 
        return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false);
     else 
        return Stream.of(supplier.get());
    

Básicamente, convierte el flujo en un Iterator para llamar hasNext() en él, y si truegire el Iterator volver a un Stream. Esto es ineficiente en el sentido de que todas las operaciones subsiguientes en el flujo pasarán por el iterador. hasNext() y next() métodos, lo que también implica que la secuencia se procesa de manera secuencial (incluso si luego se vuelve paralela). Sin embargo, esto le permite probar la secuencia sin almacenar en búfer todos sus elementos.

Probablemente hay una manera de hacer esto usando un Spliterator en lugar de un Iterator. Potencialmente, esto permite que el flujo devuelto tenga las mismas características que el flujo de entrada, incluida la ejecución en paralelo.

Si puede vivir con capacidades paralelas limitadas, la siguiente solución funcionará:

private static  Stream nonEmptyStream(
    Stream stream, Supplier e) 

    Spliterator it=stream.spliterator();
    return StreamSupport.stream(new Spliterator() 
        boolean seen;
        public boolean tryAdvance(Consumer action) 
            boolean r=it.tryAdvance(action);
            if(!seen && !r) throw e.get();
            seen=true;
            return r;
        
        public Spliterator trySplit()  return null; 
        public long estimateSize()  return it.estimateSize(); 
        public int characteristics()  return it.characteristics(); 
    , false);

Aquí hay un código de ejemplo usándolo:

List l=Arrays.asList("hello", "world");
nonEmptyStream(l.stream(), ()->new RuntimeException("No strings available"))
  .forEach(System.out::println);
nonEmptyStream(l.stream().filter(s->s.startsWith("x")),
               ()->new RuntimeException("No strings available"))
  .forEach(System.out::println);

El problema con la ejecución paralela (eficiente) es que admitir la división del Spliterator requiere una forma segura para subprocesos de notar si alguno de los fragmentos ha visto algún valor de una manera segura para subprocesos. Entonces el último de los fragmentos ejecutándose tryAdvance tiene que darse cuenta de que es el último (y tampoco pudo avanzar) para lanzar la excepción apropiada. Así que no agregué soporte para dividir aquí.

Nos puedes añadir valor a nuestro contenido tributando tu veteranía en las observaciones.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *