我有以下情况,我习惯的lambda表达式 替换工作for循环不起作用。不知道为什么会这样 失败
public class Abc implements IAbc {
// some fields
...
// field i'm interested in
@Inject @Any
private Instance<HandlerInterface> handlers;
// more members
...
// method i'm interested in
@Override
public boolean hasHandler(List<Order> orders) {
for (Order anOrder : orders) {
for (HandlerInterface aHandler : handlers) {
// following canHandler() is implemented by each
// handler that implements the HandlerInterface
if(aHandler.canHandle(anOrder)) {
return true;
}
}
return false;
}
// rest of the class content
.....
}
所以我实际上是试图在方法中替换上面的代码, 与Lambdas(我是新手)。以下是我的替换代码
public boolean hasHandler(List<Order> orders) {
return orders.stream().anyMatch(order ->
Stream.of(handlers).map(Provider::get).anyMatch(handler ->
handler.canHandle(order)));
}
上面的lambda表达式在handler.canHandle上失败了 AmbiguousResolutionException。我无法找出它为什么适用于 for循环而不是流。我确定我在这里做错了 - 但不知道是什么。非常感谢任何帮助。
答案 0 :(得分:2)
我假设Instance<HandlerInterface>
实施Iterable<HandlerInterface>
(或者您无法在增强型for循环中使用它)。
这意味着您可以通过调用Stream
Iterable
的{{1}}个元素
现在,您的方法可以转换为使用Streams,如下所示:
StreamSupport.stream(handlers.spliterator(), false);
注意:我删除了public boolean hasHandler(List<Order> orders) {
return orders.stream()
.anyMatch(o -> StreamSupport.stream(handlers.spliterator(), false)
.anyMatch(h -> h.canHandle(o)));
}
步骤,因为它在原始嵌套循环代码中没有相应的步骤。
答案 1 :(得分:0)
在这种情况下,从最里面的条件开始创建谓词
第一个谓词是
C:\windows
C:\Program Files (x86)\Python36-32
C:\Program Files (x86)\Python36-32\Scripts
C:\ProgramData\Miniconda3
C:\ProgramData\Miniconda3\Scripts
您可以在lambda中将其写为
if(aHandler.canHandle(anOrder)) {
return true;
}
第二个(虽然不是很直观)但是你想要为你的订单检查任何匹配谓词private static Predicate<? super HandlerInterface> p1(Order o) {
return h -> h.canHandle(o);
}
的处理程序,因此将其写为
p1
因此完整的解决方案变为
private static Predicate<? super Order> p2(List<HandlerInterface> handlers){
return o -> handlers.stream().anyMatch(p1(o));
}
当由于单行谓词而内联编写并删除大括号时,您可以将其重写为
orders.stream().anyMatch(p2(handlers));