【发布时间】:2018-11-21 16:11:04
【问题描述】:
我正在尝试在 orElse 中使用 Stream 并且难以理解错误。
collectorConfiguration = Optional.ofNullable(recapPlacement.getAttId())
.map(attId -> Optional.ofNullable(processorEngine.buildFrimFromAttId(attId))
.orElseThrow( () -> new OmegaException("UnableToFirmByAttId", recapPlacement.getAttId())))
.orElse( () -> Optional.ofNullable(collectorConfigurations.stream() //getting error here
.filter(cc -> recapPlacement.getPnetCode().equals(cc.getPnetCode()))
.filter(Objects::nonNull)
.findFirst())
.orElseThrow( () -> new OmegaException("CollectorCouldNotMapForPnetCode", recapPlacement.getPnetCode()))
);
在上面的代码中我正在尝试
如果
attId不为空,则获取collectorConfig如果
attId不为空且collectorConfig未找到该attId,那么我将抛出异常如果
attId为空,那么我使用pnet代码通过流collectConfigurations列表获取collectConfig如果
collectConfig未找到pnetCode,那么我将抛出异常
它在 orElse 块中给出了编译错误“Target type of a lambda expression must be an interface”。
【问题讨论】:
-
错误是什么?
-
lambda 表达式的目标类型必须是接口
-
编译复杂的流管道可能很棘手。有一些通常有用的解决问题的技术:1)向所有 lambdas 添加参数类型:
(ArgType arg) -> ...。 2) 为方法添加显式类型参数:<ArgType>.orElse(...)。 3) 将整个 lambdas 提取到局部变量。本地人通常看起来像这样:Function<Arg1, Arg2> = ...,这使得设置显式类型参数变得容易。应用这些技术通常会产生更精确的编译错误并帮助您找到问题。问题解决后,可以删除辅助类型和变量。 -
代码中用到了哪些变量?
-
我建议对
recapPlacement.getAttId()的结果使用普通的旧 if-else 测试。Stream很好,但是您在此处使用Optional的方式违反了它的 API 说明和作者的建议。请参阅The Mother of All Bikesheds 了解一些使您的代码可读的方法。
标签: java java-8 java-stream optional