¿Es posible transmitir una secuencia en Java 8?

Resuelto Phiction asked hace 10 años • 7 respuestas

¿Es posible transmitir una transmisión en Java 8? Digamos que tengo una lista de objetos, puedo hacer algo como esto para filtrar todos los objetos adicionales:

Stream.of(objects).filter(c -> c instanceof Client)

Sin embargo, después de esto, si quiero hacer algo con los clientes, necesitaría emitir cada uno de ellos:

Stream.of(objects).filter(c -> c instanceof Client)
    .map(c -> ((Client) c).getID()).forEach(System.out::println);

Esto parece un poco feo. ¿Es posible transmitir una transmisión completa a un tipo diferente? Como arrojado Stream<Object>a unStream<Client> ?

Ignore el hecho de que hacer cosas como esta probablemente significaría un mal diseño. Hacemos cosas como esta en mi clase de informática, así que estaba investigando las nuevas características de Java 8 y tenía curiosidad por saber si esto era posible.

Phiction avatar Mar 19 '14 23:03 Phiction
Aceptado

No creo que haya una manera de hacer eso de manera inmediata. Una solución posiblemente más limpia sería:

Stream.of(objects)
    .filter(c -> c instanceof Client)
    .map(c -> (Client) c)
    .map(Client::getID)
    .forEach(System.out::println);

o, como se sugiere en los comentarios, puede utilizar el castmétodo; aunque el primero puede ser más fácil de leer:

Stream.of(objects)
    .filter(Client.class::isInstance)
    .map(Client.class::cast)
    .map(Client::getID)
    .forEach(System.out::println);
assylias avatar Mar 19 '2014 16:03 assylias

Siguiendo la línea de la respuesta de ggovan , hago esto de la siguiente manera:

/**
 * Provides various high-order functions.
 */
public final class F {
    /**
     * When the returned {@code Function} is passed as an argument to
     * {@link Stream#flatMap}, the result is a stream of instances of
     * {@code cls}.
     */
    public static <E> Function<Object, Stream<E>> instancesOf(Class<E> cls) {
        return o -> cls.isInstance(o)
                ? Stream.of(cls.cast(o))
                : Stream.empty();
    }
}

Usando esta función auxiliar:

Stream.of(objects).flatMap(F.instancesOf(Client.class))
        .map(Client::getId)
        .forEach(System.out::println);
Brandon avatar Jun 12 '2014 18:06 Brandon

Tarde para la fiesta, pero creo que es una respuesta útil.

flatMapSería la forma más corta de hacerlo.

Stream.of(objects).flatMap(o->(o instanceof Client)?Stream.of((Client)o):Stream.empty())

Si oes un Client, cree una secuencia con un solo elemento; de lo contrario, utilice la secuencia vacía. Estos flujos luego se aplanarán en un formato Stream<Client>.

ggovan avatar May 05 '2014 13:05 ggovan