Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 检查流中的实例_Java_Java 8_Java Stream_Instanceof - Fatal编程技术网

Java 检查流中的实例

Java 检查流中的实例,java,java-8,java-stream,instanceof,Java,Java 8,Java Stream,Instanceof,我有以下的表达: scheduleIntervalContainers.stream() .filter(sic -> ((ScheduleIntervalContainer) sic).getStartTime() != ((ScheduleIntervalContainer)sic).getEndTime()) .collect(Collectors.toList()); …其中,scheduleIntervalContainers具有元素类型Sche

我有以下的表达:

scheduleIntervalContainers.stream()
        .filter(sic -> ((ScheduleIntervalContainer) sic).getStartTime() != ((ScheduleIntervalContainer)sic).getEndTime())
        .collect(Collectors.toList());
…其中,
scheduleIntervalContainers
具有元素类型
ScheduleContainer

final List<ScheduleContainer> scheduleIntervalContainers
最终列表scheduleIntervalContainers

是否可以在筛选之前检查类型?

您可以应用另一个
筛选
,以便仅保留
ScheduleIntervalContainer
实例,添加
映射将保存以后的强制转换:

scheduleIntervalContainers.stream()
    .filter(sc -> sc instanceof ScheduleIntervalContainer)
    .map (sc -> (ScheduleIntervalContainer) sc)
    .filter(sic -> sic.getStartTime() != sic.getEndTime())
    .collect(Collectors.toList());
或者,正如Holger所评论的,如果您喜欢lambda表达式的样式,可以使用方法引用替换该表达式:

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

一个非常优雅的选择是使用类的方法引用:

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

@solution有一个小问题-在
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());   
private静态函数选择(类clazz){
返回e->clazz.isInstance(e)?(clazz.cast(e))流:空;
}
调度间隔容器
.stream()
.flatMap(选择(ScheduleIntervalContainer.class))
.filter(sic->sic.getStartTime()!=sic.getEndTime())
.collect(Collectors.toList());

但是,为每个匹配元素创建
时可能会有性能损失。小心在庞大的数据集上使用它。我从@

.filter(ScheduleIntervalContainer.class::isInstance).map(ScheduleIntervalContainer.class::cast)
中学习了这个解决方案,无论您喜欢什么样式。在IDEA和Java8中,如果将上述代码段分配给列出scheduleIntervalContainers,它仍然提示我显式地将结果强制转换为列表scheduleIntervalContainers,您知道为什么吗?@K.Symbol您是否尝试分配给
列表
列表
?应该是后者。与使用instanceof和(ScheduleIntervalContainer)来强制转换相比,这种样式有什么好处?@MageWind这主要是样式问题。有些人喜欢它,因为您不必引入另一个变量名(用于lambda参数),其他人则喜欢它,因为它生成的字节码稍微少一些(虽然差异不足以真正相关)。这真是太酷了!但是为什么需要
.class
isInstance
不是
对象的一部分吗?
Class
是Java中的一个类吗?@PostSelf确实是,而且
ScheduleIntervalContainer
不会是一个实例。在这种方法中,您必须注意NullPointerException,因为
select(a.Class)
对于任何不是
a
的内容都将返回
null
。添加
.filter(Objects::nonNull)
会有所帮助。顺便说一句:@Eran的方法是空安全的。对不起,我的错。。。flatMap的JavaDoc说“如果映射流为空,则使用空流。”。因此,即使没有null-filter,您的解决方案也是正确的。仍然(IMO)奇怪地返回
null
,而您本可以返回一个空流