函数式编程:Java中的自引用列表(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中抱怨"fibs可能没有初始化"。虽然我认为我理解它抱怨的原因,并有一个变通办法(从本质上讲,使用setter作为尾部),但我正在寻找一个

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

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

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

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

JVM无法将未初始化的引用传递到lambda中。引用未初始化,因为构造函数调用可能失败,这与方法调用相同。Scala允许这种场景,因为生成了实现"属性"fibs而不是变量的合成类。不错的发现:一些旧的Scala编译器也不允许这种情况,并声明了一些类似"非法前向引用"(旧错误)的内容。使用Java,可以使用类似中间类或工厂方法的属性,这与Scala编译器的功能相同——只是更难看:)

最新更新