java java-8 java-stream instanceof

java - Ver instancia de en secuencia



java-8 java-stream (3)

Tengo la siguiente expresión:

scheduleIntervalContainers.stream() .filter(sic -> ((ScheduleIntervalContainer) sic).getStartTime() != ((ScheduleIntervalContainer)sic).getEndTime()) .collect(Collectors.toList());

... donde scheduleIntervalContainers tiene el tipo de elemento ScheduleContainer :

final List<ScheduleContainer> scheduleIntervalContainers

¿Es posible verificar el tipo antes del filtro?


Hay un pequeño problema con la solución @ : escribir el nombre de la clase tanto en el filter como en el map es propenso a errores; es fácil olvidarse de cambiar el nombre de la clase en ambos lugares. Una solución mejorada sería algo como esto:

private static <T, R> Function<T, Stream<R>> select(Class<R> clazz) { return e -> clazz.isInstance(e) ? Stream.of(clazz.cast(e)) : null; } scheduleIntervalContainers .stream() .flatMap(select(ScheduleIntervalContainer.class)) .filter( sic -> sic.getStartTime() != sic.getEndTime()) .collect(Collectors.toList());

Sin embargo, puede haber una penalización de rendimiento al crear un Stream para cada elemento coincidente. Tenga cuidado de usarlo en grandes conjuntos de datos. He aprendido esta solución de @ Tagir Vailev


Puede aplicar otro filter para mantener solo las instancias de ScheduleIntervalContainer , y agregar un map le ahorrará los lanzamientos posteriores:

scheduleIntervalContainers.stream() .filter(sc -> sc instanceof ScheduleIntervalContainer) .map (sc -> (ScheduleIntervalContainer) sc) .filter(sic -> sic.getStartTime() != sic.getEndTime()) .collect(Collectors.toList());

O, como comentó Holger, puede reemplazar las expresiones lambda con referencias de métodos si prefiere ese estilo:

scheduleIntervalContainers.stream() .filter(ScheduleIntervalContainer.class::isInstance) .map (ScheduleIntervalContainer.class::cast) .filter(sic -> sic.getStartTime() != sic.getEndTime()) .collect(Collectors.toList());


Una opción bastante elegante es usar la referencia de método de la clase:

scheduleIntervalContainers .stream() .filter( ScheduleIntervalContainer.class::isInstance ) .map( ScheduleIntervalContainer.class::cast ) .filter( sic -> sic.getStartTime() != sic.getEndTime()) .collect(Collectors.toList() );