web-dev-qa-db-fra.com

Existe-t-il une référence de méthode pour un no-op (NOP) utilisable pour tout ce qui est lambda?

Cela peut sembler une question étrange, mais existe-t-il un moyen de faire référence à une méthode standard sans opération (opération null, méthode null-pattern, méthode no-operation, méthode do-nothing) pour un Lambda in Java 8.

Actuellement, j'ai une méthode qui prend un, disons, void foo(Consumer<Object>), et je veux lui donner un no-op, je dois déclarer:

foo(new Consumer<Object>() { 
  public void accept(Object o) { 
    // do nothing 
  }
}

où j'aimerais pouvoir faire quelque chose comme:

foo(Object::null)

au lieu. Est-ce que quelque chose comme existe?

Je ne sais pas comment cela fonctionnerait avec des méthodes multi-paramètres - c'est peut-être une lacune dans les lambdas en Java.

55
Ben

Ce n'est pas une lacune.

Les Lambdas de Java sont des instances d’interfaces fonctionnelles; à leur tour, sont abstraites aux occurrences des constructions Java qui peuvent être simplifiées en une méthode abstraite unique ou SAM.

Mais ce SAM doit encore avoir un prototype valide. Dans votre cas, vous voulez avoir un Consumer<T> qui ne fait rien quel que soit le T.

Il doit encore être un Consumer<T> toutefois; ce qui signifie que la déclaration minimale que vous pouvez trouver est:

private static final Consumer<Object> NOOP = whatever -> {};

et utilisez NOOP là où vous en avez besoin.

48
fge

Dans votre cas particulier, vous pouvez simplement faire:

foo(i -> {});

Cela signifie que l'expression lambda reçoit un paramètre mais n'a aucune valeur de retour.

24
Anderson Vieira

Function.identity() pourrait-il répondre à vos besoins?

Retourne une fonction qui retourne toujours son argument d'entrée.

10
OldCurmudgeon

Si vous voulez une référence de méthode pour une méthode qui ne fait rien, le moyen le plus simple est d'écrire une méthode qui ne fait rien. Notez que dans cet exemple, j'ai utilisé Main::doNothing lorsqu'un Consumer<String> est requis.

class Main {

    static void doNothing(Object o) { }

    static void foo(Consumer<String> c) { }

    public static void main(String[] args) {
        foo(Main::doNothing);
    }
}

Vous pouvez également surcharger doNothing en fournissant une version utilisant varargs.

static void doNothing(Object... o) { }

Cette signature acceptera littéralement toute séquence de paramètres (même les primitives, car celles-ci seront automatiquement contrôlées). De cette façon, vous pourriez passer Main::doNothing chaque fois que la méthode de l'interface fonctionnelle a le type de retour void. Par exemple, vous pourriez passer Main::doNothing quand un ObjLongConsumer<Integer> est nécessaire.

7
Paul Boddington

Vous pouvez avoir votre propre implémentation NOOP, similaire à Function.Identity.

static <T> Consumer<T> NOOP() {
    return t -> {};
}
4
MNZ