web-dev-qa-db-ja.com

パラメーター付きのメソッド参照を使用する

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というメソッド参照をうまく使用しようとしました。 ->演算子を使用したソリューション以外のソリューションに感謝します。

パラメータと一緒にメソッド参照を使用することはどういうわけか可能ですか?ストリームのアイデアが好きで、コードを読みやすくしたいだけです。

実際には、同様の質問があると思います パラメータを使用したメソッド参照 これは読んでいますが、コード内でbind2メソッドを使用する方法がわかりません。それが唯一の解決策ですか?

33
matepal297

この目的でメソッド参照を使用することはできません。ラムダ式に頼らなければなりません。リンクされた質問の_bind2_メソッドが機能しない理由は、実際にtwoパラメーターをバインドして、3つの引数の関数を1つの引数の関数に変換しようとしているためです。 3つの引数を持つコンシューマ用の標準の関数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 -> node.findChildren(name, result));より本当に簡単ですか?

29
Holger