web-dev-qa-db-fra.com

Utiliser la référence de méthode avec le paramètre

Je viens de commencer à apprendre Java streams et j'ai rencontré un problème. Veuillez consulter l'exemple suivant. Cela fait partie d'une classe 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));
}

Mon intention était d'appeler #findChildren avec le nom et les paramètres de résultat sur chaque nœud du flux. J'ai essayé d'utiliser les méthodes de référence Node :: findChildren sans chance. J'apprécierais des solutions autres que celle avec -> opérateur.

Est-il en quelque sorte possible d'utiliser la référence de méthode avec un paramètre? J'aime l'idée des flux et je veux juste rendre le code plus lisible.

En fait, je pense qu'il y a une question similaire références de méthode avec un paramètre que j'ai lu mais ne peux pas comprendre comment utiliser la méthode bind2 dans mon code. Est-ce la seule solution?

33
matepal297

Vous ne pouvez pas utiliser de références de méthode à cette fin. Vous devez recourir à des expressions lambda. La raison pour laquelle la méthode bind2 De la question liée ne fonctionne pas est que vous essayez en fait de lier des paramètres two pour convertir une fonction à trois arguments en une fonction à un argument. Il n'y a pas de solution aussi simple car il n'y a pas de interface fonctionnel standard pour les consommateurs à trois arguments.

Il faudrait que ça ressemble

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)); pourrait alors fonctionner. Mais est-ce vraiment plus simple que .forEach(node -> node.findChildren(name, result));?

29
Holger