函数式编程:Java中的自引用列表(Fibonacci)

时间:2017-10-21 07:25:44

标签: java functional-programming lazy-evaluation fibonacci

在实现自引用懒惰列表版本以计算Java中的斐波纳契数时,我遇到了这个:

LazyList<Long> fibs = new LazyList<>(0L,
    () -> new LazyList<>(1L,
        () -> fibs.zip(fibs.getTail()).map(p -> p.getA() + p.getB()) 
    )
);

有关完整代码,请参阅https://gist.github.com/lenalebt/e627e13d034011ac156d44917fe466d3。惰性列表按需计​​算值并缓存它们以供以后重复使用。

它在第二个lambda中抱怨&#34; fibs可能没有被初始化&#34;。虽然我认为我理解为什么它抱怨并有一个解决方法(在要点中,使用尾部的setter),我正在寻找一个解决方案

  • 使用不可变的外部世界接口(因此LazyList上没有setter!)
  • 并没有完全改变那个懒惰列表的想法(实际上是来自Scala的Stream)

我知道,例如https://dzone.com/articles/do-it-java-8-recursive-and(最后一种方法)。虽然这很好用,但我想用memoization和self-reference为懒惰评估制定一个例子,而Java-Stream解决方案并没有这样做。

我试图将此示例从Scala移植到Java:http://derekwyatt.org/2011/07/29/understanding-scala-streams-through-fibonacci/

1 个答案:

答案 0 :(得分:0)

我是线程创建者的同事 - 我们已经讨论过这个问题。

JVM无法将未初始化的引用传递给lambda。引用未初始化,因为构造函数调用可能失败 - 与方法调用相同。 Scala允许这种情况,因为生成的ynthetic分类实现了“属性”fib而不是变量。很好的发现:一些旧的Scala编译器也不允许这种情况,并声明类似“非法前向引用”(旧错误)。使用Java,可以使用类似属性的中间类或工厂方法,它与Scala编译器相同 - 只是更丑陋:)