qum*_*uma 62 java instanceof java-8 java-stream
我有以下表达式:
scheduleIntervalContainers.stream()
.filter(sic -> ((ScheduleIntervalContainer) sic).getStartTime() != ((ScheduleIntervalContainer)sic).getEndTime())
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
... scheduleIntervalContainers
元素类型在哪里ScheduleContainer
:
final List<ScheduleContainer> scheduleIntervalContainers
Run Code Online (Sandbox Code Playgroud)
是否可以在过滤器之前检查类型?
小智 106
一个非常优雅的选择是使用类的方法引用:
scheduleIntervalContainers
.stream()
.filter( ScheduleIntervalContainer.class::isInstance )
.map( ScheduleIntervalContainer.class::cast )
.filter( sic -> sic.getStartTime() != sic.getEndTime())
.collect(Collectors.toList() );
Run Code Online (Sandbox Code Playgroud)
Era*_*ran 89
您可以应用另一个filter
以便仅保留ScheduleIntervalContainer
实例,并添加一个map
将保存以后的转换:
scheduleIntervalContainers.stream()
.filter(sc -> sc instanceof ScheduleIntervalContainer)
.map (sc -> (ScheduleIntervalContainer) sc)
.filter(sic -> sic.getStartTime() != sic.getEndTime())
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
或者,正如Holger所评论的,如果您喜欢该样式,则可以使用方法引用替换lambda表达式:
scheduleIntervalContainers.stream()
.filter(ScheduleIntervalContainer.class::isInstance)
.map (ScheduleIntervalContainer.class::cast)
.filter(sic -> sic.getStartTime() != sic.getEndTime())
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
And*_*rey 13
@ Eran解决方案存在一个小问题- 在两者中键入类名filter
并且map
容易出错 - 很容易忘记在两个地方更改类的名称.一个改进的解决方案是这样的:
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());
Run Code Online (Sandbox Code Playgroud)
但是,Stream
为每个匹配元素创建一个性能可能会受到影响.小心在大型数据集上使用它.我从@ Tagir Vailev那里学到了这个解决方案