用于替换嵌套for循环的Lambda表达式由于某种原因不起作用

时间:2018-05-04 07:14:00

标签: java lambda java-8 java-stream

我有以下情况,我习惯的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循环而不是流。我确定我在这里做错了 - 但不知道是什么。非常感谢任何帮助。

2 个答案:

答案 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));