2016-03-02 5 views
33

Ich habe den folgenden Ausdruck:Java 8 Stream - überprüfen, ob Instanceof

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

wo scheduleIntervalContainers vom Typ ScheduleContainer ist

final List<ScheduleContainer> scheduleIntervalContainers 

Gibt es eine Möglichkeit sich die Art vor dem Filter zu überprüfen?

Antwort

43

Sie können einen anderen filter anwenden, um nur die ScheduleIntervalContainer Instanzen zu halten, und eine map Zugabe wird Ihnen die später Abgüsse sparen:

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

gelernt Oder '.filter (ScheduleIntervalContainer.class :: isInstance) .map (ScheduleIntervalContainer.class :: cast)', welcher Stil Sie bevorzugen. – Holger

56

Eine recht elegante Option ist Methode Referenz-Klasse zu verwenden:

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

es gibt ein kleines Problem mit @Eran Lösung - Typisierung Klassennamen in beide filter und map ist fehleranfällig - es ist einfach zu ch zu vergessen An beiden Orten den Namen der Klasse angeben. Eine verbesserte Lösung wäre so etwas wie diese:

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

Allerdings könnte es eine Leistungseinbuße, ein Stream für jedes Anpassungselement zu schaffen. Seien Sie vorsichtig, um es für große Datenmengen zu verwenden. Ich habe diese Lösung von @Tagir Vailev