Подтвердить что ты не робот

Есть ли ссылка метода для 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.

4b9b3361

Ответ 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 -> {};
}