45

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 メソッドを使用する方法がわかりません。それが唯一の解決策ですか?

4

1 に答える 1

44

この目的でメソッド参照を使用することはできません。ラムダ式に頼る必要があります。bind2リンクされた質問の方法が機能しない理由は、実際に2 つのパラメーターをバインドして、3 つの引数の関数を 1 つの引数の関数に変換しようとしているためです。interface引数が 3 つのコンシューマには標準関数がないため、同様に単純なソリューションはありません。

次のように見える必要があります

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

于 2015-04-24T10:24:49.343 に答える