是否有一个可用于任何 lambda 的 no-op (NOP)的方法引用?

这听起来像是一个奇怪的问题,但是有没有一种方法可以引用 Java 8中 Lambda 的标准 no-op 方法(也就是 null 操作、 null 模式方法、 no-operation、 do-nothing 方法)。

目前,我有一个方法,它接受一个,比如说,void foo(Consumer<Object>),我想给它一个 no-op,我必须声明:

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

我希望能够做一些事情,比如:

foo(Object::null)

有什么东西存在吗?

不确定如何使用多参数方法——也许这是 Java 中 lambdas 的一个缺陷。

60743 次浏览

This is no deficiency.

Lambdas in Java are instances of functional interfaces; which, in turn, are abstracted to instances of Java constructs which can be simplified to one single abstract method, or SAM.

But this SAM still needs to have a valid prototype. In your case, you want to have a no-op Consumer<T> which does nothing whatever the T.

It still needs to be a Consumer<T> however; which means the minimal declaration you can come up with is:

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

and use NOOP where you need to.

In your particular case you could simply do:

foo(i -> {});

This means that the lambda expression receives a parameter but has no return value.

The equivalent code for a BiConsumer<T, U> would be:

void bifoo(BiConsumer<Object, Object> consumer) { ... }


bifoo((a, b) -> {});

Could Function.identity() fit your needs?

Returns a function that always returns its input argument.

If you want a method reference for a method that does nothing, the easiest way is to write a method that does nothing. Notice that in this example I have used Main::doNothing when a Consumer<String> is required.

class Main {


static void doNothing(Object o) { }


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


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

You could also overload doNothing by providing a version using varargs.

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

This signature will accept literally any sequence of parameters (even primitives, as these will get autoboxed). That way you could pass Main::doNothing whenever the functional interface's method has void return type. For example you could pass Main::doNothing when an ObjLongConsumer<Integer> is needed.

You can have your own NOOP implementation, similar to Function.Identity.

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

If you want something that is very close to a no-op, you can use Objects::requireNonNull.

Using x -> {} also works of course, but your IDE's auto-formatter may try to split it up onto multiple lines.