使用带参数的方法引用

Posted

技术标签:

【中文标题】使用带参数的方法引用【英文标题】:Use method reference with parameter 【发布时间】:2015-07-02 08:14:16 【问题描述】:

我刚开始学习 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));

我的意图是使用流中每个节点上的名称和结果参数调用#findChildren。我尝试使用引用 Node::findChildren 的方法,但没有成功。我会很感激使用 -&gt; 运算符的其他解决方案。

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

实际上,我认为有一个类似的问题Method references with a parameter 我读过,但无法弄清楚如何在我的代码中使用 bind2 方法。它是唯一的解决方案吗?

【问题讨论】:

您只能在需要具有类似签名的功能接口的地方传递方法引用(即可以推断 lambda 的参数) forEach() 需要单个 Node 参数并返回 void,因此只能在此处传递接受单个 Node 的静态方法的引用,或者返回 void 的 Node 类的无参数方法。解决方法:自己创建这样的方法。 marcin-chwedczuk.github.io/method-references-in-java-8 是人们研究带参数的方法引用的一些很好的例子。 【参考方案1】:

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

它必须看起来像

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

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

【讨论】:

谢谢!带有 2 个参数的 Node::findChildren 如何转换为接受 3 个参数的 ThreeConsumer? 对于非static的方法,你必须把方法接收者算作参数。在您的特定情况下,使用 Node 实例作为参数调用消费者,将在其上调用 findChildren 方法。好吧,如果您使用ClassName::methodName 来引用实例方法,这适用。相反,您可以通过说object::methodName 将方法引用绑定到特定接收器,然后该方法将在object 上调用。发生这种情况,例如当你说System.out::println 时,方法println 将在System.out 中找到的PrintStream 实例上调用。 但在您的情况下,您希望处理不同Node 实例的流,因此您想要让接收器未绑定并将其计为参数。另见here 又是一个令人费解的时刻,只是为了发现“你不能”。

以上是关于使用带参数的方法引用的主要内容,如果未能解决你的问题,请参考以下文章

委托的使用二

CefSharp的引用配置实例

TypeScript带引用和push()方法的对象数组

excel表格引用公式的方法步骤

java8中的方法引用与构造器引用

硬核两万字文章带你C++入门