2016-03-02 19 views
33

ho la seguente espressione:Java 8 Stream - controllare se instanceof

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

dove scheduleIntervalContainers è di tipo ScheduleContainer

final List<ScheduleContainer> scheduleIntervalContainers 

Esiste una possibilita 'di controllare il tipo prima del filtro?

risposta

43

È possibile applicare un altro filter al fine di mantenere solo le ScheduleIntervalContainer casi, e l'aggiunta di un map vi farà risparmiare i calchi successivi:

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

Oppure '.filter (ScheduleIntervalContainer.class :: isInstance) .map (ScheduleIntervalContainer.class :: cast)', qualunque sia lo stile che preferisci. – Holger

56

Un'opzione abbastanza elegante è quella di utilizzare il metodo di riferimento della classe:

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

C'è un piccolo problema con @Eran soluzione - a digitare il nome della classe sia in filter e map è soggetto a errori - è facile dimenticare a ch aggiungi il nome della classe in entrambi i posti. Una migliore soluzione sarebbe qualcosa di simile:

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

Tuttavia ci potrebbe essere una riduzione delle prestazioni nella creazione di un Stream per ogni elemento corrispondente. Fai attenzione a usarlo su enormi set di dati. Ho appreso questa soluzione da @Tagir Vailev