在 Java 中使用 Stream 和 BinaryOperator 的 Fibonacci
Fibonacci using Stream And BinaryOperator in Java
我是学生,我正在学习函数式 Java 8. 我有项目要做,但我不明白这个函数接口是如何工作的。我的老师告诉我 "you should know that",我正在寻求帮助来理解这个问题。应该算斐波那契数列
我得到了这个代码
StreamUtils.generateRest(Stream.of(1, 1), (a, b) -> a + b)
.limit(7)
.forEach(System.out::println);
StreamUtils.generateRest(Stream.of("AAA", "BB", "KKKK"), (a, b) -> a + b)
.limit(7)
.forEach(System.out::println);
StreamUtils.generateRest(Stream.of(i -> 0),
(BinaryOperator<UnaryOperator<Integer>>) (f, g) -> (x -> x == 0 ? 1 : x * g.apply(x - 1)))
.limit(10)
.map(f -> f.apply(7))
.forEach(System.out::println);
我做了类似的事情,但它不起作用
public class StreamUtils<T> {
public static <T> Stream generateRest(Stream<T> stream, BinaryOperator<T> binaryOperator) {
return Stream.of(stream.reduce((a, b) -> binaryOperator.apply(a, b)));
}
}
有人可以帮助我并解释如何解决这个问题吗?
要使第一个示例工作,您需要实现如下内容:
private static class StreamUtils<T> {
public static <T> Stream generateRest(Stream<T> stream, BinaryOperator<T> binaryOperator) {
return Stream.iterate(stream.toArray(), p -> new Object[]{p[1], binaryOperator.apply((T) p[0], (T) p[1])})
.flatMap(p -> Stream.of(p[0]));
}
}
它从您的输入流创建数组,然后将传递的函数应用于两个元素,将上一次迭代的结果移动到位置 0
,因为我们需要前两个值来计算下一个。
然后它会创建无限的计算斐波那契元素流。
输出为:
1
1
2
3
5
8
13
以及正确使用泛型的版本,因为您的初始结构会生成原始类型。
private static class StreamUtils {
public static <T> Stream<T> generateRest(Stream<T> stream, BinaryOperator<T> binaryOperator) {
return Stream.iterate(stream.toArray(), p -> new Object[]{p[1], binaryOperator.apply((T) p[0], (T) p[1])})
.flatMap(p -> Stream.of((T) p[0]));
}
}
我假设超过 2 项表示 A、B、C、A+B、B+C、C+(A+B)、(A+B)+(B+C) 等., 有1项表示A, A+A, A+(A+A), (A+A)+(A+(A+A)), 等等, 其中+是二元运算符.
基本上你把流变成一个数组,然后你使用 Stream.generate
并且在每一步你在你拥有的元素之后生成元素,将数组向左移动以适应新元素,并且 return 旧的第一个元素(不再在数组中)。请注意,由于这有副作用(修改外部数组),因此不能与 .parallel()
.
一起使用
@SuppressWarnings("unchecked")
public static <T> Stream<T> generateRest(Stream<T> stream, BinaryOperator<T> binaryOperator) {
T[] t = (T[]) stream.toArray();
if (t.length == 1) {
t = (T[]) new Object[] { t[0], binaryOperator.apply(t[0], t[0]) };
}
final T[] items = t;
return Stream.generate(() -> {
T first = items[0];
T next = binaryOperator.apply(items[0], items[1]);
System.arraycopy(items, 1, items, 0, items.length - 1);
items[items.length - 1] = next;
return first;
});
}
输出:
1
1
2
3
5
8
13
AAA
BB
KKKK
AAABB
BBKKKK
KKKKAAABB
AAABBBBKKKK
0
0
0
0
0
0
0
0
5040
5040
我是学生,我正在学习函数式 Java 8. 我有项目要做,但我不明白这个函数接口是如何工作的。我的老师告诉我 "you should know that",我正在寻求帮助来理解这个问题。应该算斐波那契数列
我得到了这个代码
StreamUtils.generateRest(Stream.of(1, 1), (a, b) -> a + b)
.limit(7)
.forEach(System.out::println);
StreamUtils.generateRest(Stream.of("AAA", "BB", "KKKK"), (a, b) -> a + b)
.limit(7)
.forEach(System.out::println);
StreamUtils.generateRest(Stream.of(i -> 0),
(BinaryOperator<UnaryOperator<Integer>>) (f, g) -> (x -> x == 0 ? 1 : x * g.apply(x - 1)))
.limit(10)
.map(f -> f.apply(7))
.forEach(System.out::println);
我做了类似的事情,但它不起作用
public class StreamUtils<T> {
public static <T> Stream generateRest(Stream<T> stream, BinaryOperator<T> binaryOperator) {
return Stream.of(stream.reduce((a, b) -> binaryOperator.apply(a, b)));
}
}
有人可以帮助我并解释如何解决这个问题吗?
要使第一个示例工作,您需要实现如下内容:
private static class StreamUtils<T> {
public static <T> Stream generateRest(Stream<T> stream, BinaryOperator<T> binaryOperator) {
return Stream.iterate(stream.toArray(), p -> new Object[]{p[1], binaryOperator.apply((T) p[0], (T) p[1])})
.flatMap(p -> Stream.of(p[0]));
}
}
它从您的输入流创建数组,然后将传递的函数应用于两个元素,将上一次迭代的结果移动到位置 0
,因为我们需要前两个值来计算下一个。
然后它会创建无限的计算斐波那契元素流。
输出为:
1
1
2
3
5
8
13
以及正确使用泛型的版本,因为您的初始结构会生成原始类型。
private static class StreamUtils {
public static <T> Stream<T> generateRest(Stream<T> stream, BinaryOperator<T> binaryOperator) {
return Stream.iterate(stream.toArray(), p -> new Object[]{p[1], binaryOperator.apply((T) p[0], (T) p[1])})
.flatMap(p -> Stream.of((T) p[0]));
}
}
我假设超过 2 项表示 A、B、C、A+B、B+C、C+(A+B)、(A+B)+(B+C) 等., 有1项表示A, A+A, A+(A+A), (A+A)+(A+(A+A)), 等等, 其中+是二元运算符.
基本上你把流变成一个数组,然后你使用 Stream.generate
并且在每一步你在你拥有的元素之后生成元素,将数组向左移动以适应新元素,并且 return 旧的第一个元素(不再在数组中)。请注意,由于这有副作用(修改外部数组),因此不能与 .parallel()
.
@SuppressWarnings("unchecked")
public static <T> Stream<T> generateRest(Stream<T> stream, BinaryOperator<T> binaryOperator) {
T[] t = (T[]) stream.toArray();
if (t.length == 1) {
t = (T[]) new Object[] { t[0], binaryOperator.apply(t[0], t[0]) };
}
final T[] items = t;
return Stream.generate(() -> {
T first = items[0];
T next = binaryOperator.apply(items[0], items[1]);
System.arraycopy(items, 1, items, 0, items.length - 1);
items[items.length - 1] = next;
return first;
});
}
输出:
1
1
2
3
5
8
13
AAA
BB
KKKK
AAABB
BBKKKK
KKKKAAABB
AAABBBBKKKK
0
0
0
0
0
0
0
0
5040
5040