Как может ссылка на лямбда-выражение Java сама по себе?

Я обнаружил, что эта статья очень информативна по сравнению функций старого стиля с новыми Java- 8 лямбда-функций и параллельная обработка. Единственное, что я не мог понять, было одно ограничение на лямбда-функции: со страницы 4:

  

3.3 Предварительные условия   Хотя лямбда-выражения предназначены для более   цис альтернатива   AIC   они не полная замена.   Есть несколько предварительных условий, которые   LambdaFicator   проверки   перед рефакторингом   AIC   в лямбда-выражение. Эти   предварительные условия являются неотъемлемой частью того, как лямбда-выражения   реализовано в Java, а не в ограничениях нашего инструмента.   (Р1)   AIC   должен создать экземпляр из интерфейса. Экземпляры   абстрактные или конкретные классы не могут быть преобразованы в лямбду   выражения.   (Р2)   AIC   не должно иметь полей и объявлять только один метод.   Лямбда-выражение представляет собой одну анонимную функцию   Тион; следовательно,   AIC   с несколькими методами не может быть   преобразуется в одно лямбда-выражение.   (Р3)   AIC   не должно быть ссылок на   этот   или же   супер   , В   лямбда-выражение,   этот   а также   супер   лексически ограничены,   Это означает, что они интерпретируются так же, как и в   окружающая среда, например, как если бы они появились в государстве   перед лямбда-выражением [6]. Однако в   AIC   они относятся к самому внутреннему классу.   (Р4)   AIC   не должен объявлять рекурсивный метод. Чтобы   выполнить рекурсивный вызов, мы должны получить ссылку на   анонимная функция. В то время как   LambdaFicator   мог выполнить   этот рефакторинг, это может привести к ненужной сложности   в код и вреда понятности.

На P4 «AIC не должен объявлять рекурсивный метод ... LambdaFicator мог бы выполнить этот рефакторинг ...», как можно реорганизовать лямбда-выражение для ссылки на себя? Поскольку по определению эти лямбда-анонимные функции не имеют имени, на которое можно ссылаться, и не имеют ссылки на себя (см. P3 выше).?

7 голосов | спросил NoBugs 4 Jam1000000amSun, 04 Jan 2015 07:48:41 +030015 2015, 07:48:41

3 ответа


0
public class Test {
    static Runnable r;

    public static void main(String... args) {
        r = () -> r.run();
        r.run();
    }
}

Runnable получает ссылку на себя из поля r при запуске.

Вы также можете использовать массив длины 1 для хранения ссылки, если вам не нравится добавлять поле.

ответил Alex 4 Jam1000000amSun, 04 Jan 2015 08:08:37 +030015 2015, 08:08:37
0

Как уже говорилось здесь , каноническим способом реализации рекурсивной функции в Java является метод :

public static int fib(int n) {
    return n==0? 0: n==1? 1: fib(n-1)+fib(n-2);
}

Тогда, если вам нужен экземпляр, выполняющий функционал interface, вы можете использовать ссылку на метод:

Function<Integer, Integer> fib = MyClass::fib;

или

IntUnaryOperator fib0=MyClass::fib;

Это наиболее близкий эквивалент лямбда-выражения, поскольку лямбда-выражение является не только синтаксическим сахаром для сгенерированного во время выполнения класса, заменяющего анонимный внутренний класс, но и для анонимного метода, содержащего код для реализации одного абстрактного метода. р>

Использование обычного рекурсивного метода превращает анонимный метод в именованный, сохраняя все остальные свойства лямбда-выражений. Это отличается от всех других обходных путей, пытающихся дать лямбда-выражению ссылку на себя, как, например, сохранение экземпляра в поле. Эти обходные пути не являются семантически эквивалентными (и менее эффективными).

ответил Holger 5 Jpm1000000pmMon, 05 Jan 2015 12:48:56 +030015 2015, 12:48:56
0

Получено из ответа @ Alex:

@FunctionalInterface
public interface SelfRunnable extends Runnable {
  public void run(SelfRunnable this_);

  @Override
  public default void run() {
    run(this);
  }

  public static Runnable runnable(SelfRunnable runnable) {
    return runnable;
  }
}

public interface Test {
  public static void main(String... arguments) {
    final Runnable r = SelfRunnable.runnable(this_ -> this_.run());
    r.run();
  }
}
ответил srborlongan 4 Jam1000000amSun, 04 Jan 2015 09:38:57 +030015 2015, 09:38:57

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132