检查流中的instanceof

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)

  • 或者`.filter(ScheduleIntervalContainer.class :: isInstance).map(ScheduleIntervalContainer.class :: cast)`,无论你喜欢哪种风格. (99认同)

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那里学到了这个解决方案

  • 当你本可以返回一个空流时,仍然(IMO)返回“null”很奇怪 (4认同)