2016-03-02 83 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