在Java中使用Stream和BinaryOperator的斐波那契

时间:2019-04-15 16:13:59

标签: java lambda java-8 java-stream functional-interface

我是学生,而且我正在学习Java8。我有项目要做,但我不了解此函数接口的工作方式。我的老师告诉我“您应该知道这一点”,我正在寻求帮助以了解此问题。应该算斐波那契数列

我收到了这段代码

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)));
    }

}

有人可以帮助我,并解释如何解决此问题?

2 个答案:

答案 0 :(得分:2)

要使第一个示例工作,您需要实现以下类似内容:

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]));
    }
}

答案 1 :(得分:1)

我假设具有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))等,其中+是二元运算符。

基本上,您将流转换为数组,然后使用#testing starting_value = 4; train_data = np.load('training_data-{}.npy'.format(starting_value)) for data in train_data: img = cv2.imread(data[0]) choice = data[1] cv2.imshow('test', img) print(choice) if cv2.waitKey(25) & 0xFF == ord('q'): cv2.destroyAllWindows() break ,并在每个步骤之后生成元素,然后将数组左移以适合新元素,并返回旧的第一个元素(不再在数组中)。请注意,由于这样做有副作用(修改外部数组),因此不能与Stream.generate一起使用。

.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;
    });
}