问题
In my previous Question here
Infinite Fibonacci Sequence with Memoized in Java 8
I asked how to write a code to define the infinite sequence of fibonacci in concise math manner with memoization with Java8 Stream.
Thankfully, I've got an answer, and the code below seems to work well:
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
Although the code style presentation of the function in Java8 still confuses me, I could fairly confirm it corresponds the math definition of fibonacci sequence.
The computing speed suggests it memoizes the function, and he says
You can take your map-based memoized fibonacci(x) and make an infinite stream out of it like this:
What is the map-based memoized
in Java8?
Also, I could not follow the logical role of
.mapToLong(f -> f[0]);
Can you explain. Any reference/documentation is also appreciated. Thanks.
回答1:
As Misha said, it's the Supplier<Long>
functional interface that's memoised because it stores two private variables n1
and n2
. The object has then a mutable state and has side effects. It could cause problems when using paralellization.
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;
}
}
At opposite the solution with the iterate
is immutable and is ready for parallelization. It generates a stream of long
arrays of size 2, starting from [1,1] and iteratively applying the function f -> new long[]{f[1], f[0] + f[1]}
.iterate(
new long[]{1, 1},
f -> new long[]{f[1], f[0] + f[1]}
)
来源:https://stackoverflow.com/questions/26290716/map-based-memoized-in-java8