【问题标题】:`map-based memoized` in Java8?Java8中的“基于地图的记忆”?
【发布时间】:2014-12-05 02:37:39
【问题描述】:

在我之前的问题中

Infinite Fibonacci Sequence with Memoized in Java 8

我问如何编写代码以简洁的数学方式定义斐波那契的无限序列,并使用 Java8 Stream 进行记忆。

谢天谢地,我得到了答案,下面的代码似乎运行良好:

    LongStream fibs = Stream
            .iterate(
            new long[]{1, 1},
            f -> new long[]{f[1], f[0] + f[1]}
            )
            .mapToLong(f -> f[0]);

    fibs
            .limit(30)
            .forEach(System.out::println);

1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040

虽然 Java8 中函数的代码风格表示仍然让我感到困惑,但我可以相当确认它对应于斐波那契数列的数学定义。

计算速度表明它可以记住函数,他说

您可以使用基于地图的记忆斐波那契 (x) 并从中生成无限流,如下所示:

Java8 中的map-based memoized 是什么?

另外,我无法遵循逻辑角色

.mapToLong(f -> f[0]);

你能解释一下吗?任何参考/文档也值得赞赏。谢谢。

【问题讨论】:

  • 我认为您误解了您引用的评论。它指的是IntStream.iterate(1,i->i+1).mapToLong(i->fibonacci(i)); 在原来的问题中,你有一个记忆斐波那契函数的定义,但说“这不是一个无限序列”。所以我展示了如何使用已经记忆的函数来制作无限流。

标签: java dictionary functional-programming java-8 java-stream


【解决方案1】:

正如 Misha 所说,被记忆的是 Supplier<Long> functional interface,因为它存储了两个私有变量 n1n2。然后该对象具有 可变 状态并具有副作用。使用并行化可能会导致问题。

new Supplier<Long>() {
    private long n1 = 1;
    private long n2 = 2;

    @Override
    public Long get() {
        long fibonacci = n1;
        long n3 = n2 + n1;
        n1 = n2;
        n2 = n3;
        return fibonacci;
    }
}

相反,iterate 的解决方案是不可变的,可以并行化。它生成一个大小为 2 的 long 数组流,从 [1,1] 开始并迭代地应用函数 f -&gt; new long[]{f[1], f[0] + f[1]}

.iterate(
        new long[]{1, 1},
        f -> new long[]{f[1], f[0] + f[1]}
        )

【讨论】:

    猜你喜欢
    • 2017-01-19
    • 2014-12-29
    • 1970-01-01
    • 2015-04-30
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多