使用Java8从列表中获取子类的第一个实例

使用Java8从列表中获取子类的第一个实例,java,java-8,java-stream,Java,Java 8,Java Stream,我有一个类的两个子类。现在我有了一个列表,它可以包含任何一个子类 现在我需要遍历这个列表,得到第一个出现的子类B 我使用了下面的方法,寻找Java8/stream/lambda实现这一点的方法 SeniorEmployee sEmp = null; for(Employee emp: empList){ if(emp instanceof SeniorEmployee) sEmp = emp; break; } 那么: SeniorEmployee sEmp = emp.strea

我有一个类的两个子类。现在我有了一个列表,它可以包含任何一个子类

现在我需要遍历这个列表,得到第一个出现的子类B

我使用了下面的方法,寻找Java8/stream/lambda实现这一点的方法

SeniorEmployee sEmp = null;    
for(Employee emp: empList){
if(emp instanceof SeniorEmployee)
 sEmp = emp;
 break;
}
那么:

SeniorEmployee sEmp = emp.stream()
                         .filter(SeniorEmployee.class::isInstance)
                         .findFirst()
                         .map(SeniorEmployee.class::cast)
                         .orElse(null);
您可以在
orElse
部分中输入一些其他默认值。此解决方案用于获取与
谓词匹配的第一个元素


还要注意,
orElse(null)
将使代码与问题中的代码等效。最好给出一个非
null
的值,因为这违背了
可选的

orElse(null)
与问题中的命令式样式相匹配的全部目的。挑剔:
过滤器(SeniorEmployee.class::isInstance)
会更好,因为它不会为lambda创建额外的内部类。@VGR这主要是一个样式问题,所以它应该是一致的,即
.filter(SeniorEmployee.class::isInstance).map(SeniorEmployee.class::cast)
filter(x->x instanceof SeniorEmployee.map(x->(SeniorEmployee)x)
。如果是关于最小的性能,这可能会令人惊讶,但在当前的实现中,lambda表达式在这里更有效,因为它们是非捕获的,因此可以重用。lambda将没有“内部类”,而是运行时生成的匿名类,与方法引用没有什么不同。我不喜欢使用
orElse(null)
,它实际上反对使用
可选的
对象。为什么不在以后的过程中使用
sEmp.isPresent()
,而不是再次使用ol'bad nullcheck@YassinHajaj是的,这仅仅是为了让它与OP的代码等效:不正确的大括号不会让这个编译。如果列表中没有高级员工,这是一个非例外的情况,我认为是这样的,最好返回
可选的
,而不是
高级员工
。将来它可能会为您节省大量空检查或NPE。