Есть ли ссылка метода для no-op (NOP), которая может использоваться для чего-либо лямбда?
Это может звучать как странный вопрос, но есть ли способ ссылаться на стандартный метод no-op (aka null, метод null-pattern, no-operation, do-nothing method) для Lambda в Java 8.
В настоящее время у меня есть метод, который принимает, скажем, void foo(Consumer<Object>)
, и я хочу дать ему no-op, я должен объявить:
foo(new Consumer<Object>() {
public void accept(Object o) {
// do nothing
}
}
где я хотел бы иметь возможность сделать что-то вроде:
foo(Object::null)
вместо этого. Что-то вроде существует?
Не уверен, как это будет работать с многопараметрическими методами - возможно, это недостаток в lambdas в Java.
Ответы
Ответ 1
Это не недостаток.
Lambdas в Java - это примеры функциональных интерфейсов; которые, в свою очередь, абстрагируются на экземпляры Java-конструкций, которые могут быть упрощены до одного абстрактного метода или SAM.
Но этот SAM еще должен иметь действительный прототип. В вашем случае вы хотите иметь no-op Consumer<T>
, который ничего не делает T
.
Тем не менее, он все равно должен быть Consumer<T>
; что означает минимальное объявление, которое вы можете найти:
private static final Consumer<Object> NOOP = whatever -> {};
и используйте NOOP
, где вам нужно.
Ответ 2
В вашем конкретном случае вы можете просто сделать:
foo(i -> {});
Это означает, что выражение лямбда получает параметр, но не имеет возвращаемого значения.
Ответ 3
Может ли Function.identity() соответствовать вашим потребностям?
Возвращает функцию, которая всегда возвращает свой входной аргумент.
Ответ 4
Если вам нужна ссылка метода для метода, который ничего не делает, самый простой способ - написать метод, который ничего не делает. Обратите внимание, что в этом примере я использовал Main::doNothing
, когда требуется Consumer<String>
.
class Main {
static void doNothing(Object o) { }
static void foo(Consumer<String> c) { }
public static void main(String[] args) {
foo(Main::doNothing);
}
}
Вы также можете перегрузить doNothing
, предоставив версию с использованием varargs.
static void doNothing(Object... o) { }
Эта подпись будет принимать буквально любую последовательность параметров (даже примитивов, так как они будут получать автобокс). Таким образом, вы можете передать Main::doNothing
всякий раз, когда метод функционального интерфейса имеет тип возврата void
. Например, вы можете пройти Main::doNothing
, когда требуется ObjLongConsumer<Integer>
.
Ответ 5
У вас может быть ваша собственная реализация NOOP, похожая на Function.Identity.
static <T> Consumer<T> NOOP() {
return t -> {};
}