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