2016-03-02 57 views
33

我有以下表現:Java的8個流 - 檢查的instanceof

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

其中scheduleIntervalContainers的類型是ScheduleContainer

final List<ScheduleContainer> scheduleIntervalContainers 

的是否有posibility檢查過濾器之前的類型?

回答

43

您可以以只保留ScheduleIntervalContainer實例應用其他filter,並添加map將節省您以後的石膏:

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

或者'.filter(ScheduleIntervalContainer.class :: isInstance).map(ScheduleIntervalContainer.class :: cast)''學到了這個解決方案,無論你喜歡什麼樣的風格。 – Holger

56

一個漂亮優雅的選擇是使用類的方法參考:

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

有一個小問題,@Eran的解決方案 - 在這兩個filtermap打字類名容易出錯 - 它很容易忘記CH在兩個地方都把班級的名字變成了憤怒。改進的辦法是這樣的:

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

但是有可能是在創造每一個匹配元素的Stream的性能損失。請注意在龐大的數據集上使用它。我從@Tagir Vailev