How can a Java lambda-expression reference itself?

后端 未结 3 1893
悲哀的现实
悲哀的现实 2021-02-04 16:27

I found this article to be very informative in comparison of old-style functions to new Java-8 lambda-functions and parallel processing. One thing I couldn\'t quite understand w

相关标签:
3条回答
  • 2021-02-04 16:45
    public class Test {
        static Runnable r;
    
        public static void main(String... args) {
            r = () -> r.run();
            r.run();
        }
    }
    

    The Runnable obtains a reference to itself from the field r when it is run.

    You could also use a length 1 array to store the reference if you don't like adding a field.

    0 讨论(0)
  • 2021-02-04 16:45

    As said here, Java’s canonical way to implement a recursive function is a method:

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

    Then, if you need a instance fulfilling a functional interface you can use a method reference:

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

    or

    IntUnaryOperator fib0=MyClass::fib;
    

    This is the closest equivalent to a lambda expression as a lambda expression is not just syntactic sugar for a runtime generated class replacing the anonymous inner class but also for an anonymous method hosting the code of the single abstract method to implement.

    Using an ordinary recursive method turns the anonymous method into a named one while maintaining all other properties of lambda expressions. This differs from all other workarounds trying to give a lambda expression a reference to itself, like storing the instance into a field. These workarounds are not semantically equivalent (and less efficient).

    0 讨论(0)
  • 2021-02-04 17:06

    Derived from @Alex's answer:

    @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();
      }
    }
    
    0 讨论(0)
提交回复
热议问题