使用带参数的方法引用

mat*_*297 35 java lambda java-stream functional-interface method-reference

我刚开始学习Java流并遇到了问题.请看下面的例子.这是Node类的一部分:

private Map<String, Node> nodes;

public Optional<Node> child(String name) {
    return Optional.<Node>ofNullable(nodes.get(name));
}

private void findChildren(String name, List<Node> result) {
    child(name).ifPresent(result::add);
    nodes.values().stream()
//          .map(Node::findChildren(name, result))
//          .forEach(Node::findChildren(name, result))
            .forEach(node -> node.findChildren(name, result));
}
Run Code Online (Sandbox Code Playgroud)

我的目的是使用流中每个节点上的名称和结果参数调用#findChildren.我试图使用方法引用Node :: findChildren没有运气.我很欣赏其他与->运营商合作的解决方案.

是否有可能将方法引用与参数一起使用?我喜欢流的想法,我只想让代码更具可读性.

实际上,我认为有一个类似的问题方法引用与我读过的参数,但无法弄清楚如何在我的代码中使用bind2方法.这是唯一的解决方案吗?

Hol*_*ger 31

您不能为此目的使用方法引用.你必须求助于lambda表达式.bind2链接问题的方法不起作用的原因是您实际上尝试绑定两个参数以将三个arg函数转换为一个arg函数.没有类似简单的解决方案,interface因为三个arg消费者没有标准功能.

它必须看起来像

interface ThreeConsumer<T, U, V> {
    void accept(T t, U u, V v);
}
public static <T, U, V> Consumer<T> bind2and3(
                        ThreeConsumer<? super T, U, V> c, U arg2, V arg3) {
    return (arg1) -> c.accept(arg1, arg2, arg3);
}
Run Code Online (Sandbox Code Playgroud)

然后.forEach(bind2and3(Node::findChildren, name, result));可以工作.但这真的比这简单.forEach(node -> node.findChildren(name, result));吗?

  • 又是一个大脑融化的小时,只是为了发现“你不能”。 (4认同)
  • 对于非"静态"方法,您必须将方法接收器计为参数.在您的特定情况下,使用`Node`实例作为参数调用使用者,将在其上调用`findChildren`方法.好吧,这适用于使用`ClassName :: methodName`来引用实例方法.相反,您可以通过说"object :: methodName"将方法引用绑定到特定接收器,然后在`object`上调用该方法.发生这种情况,例如,当您说`System.out :: println`时,将在`System.out`中的`PrintStream`实例上调用方法`println`. (3认同)