为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

有只小跳蛙 2022-10-07 16:22:20
我是学生,正在学习函数式 Java 8。我有项目要做,但我不明白这个函数接口是如何工作的。我的老师告诉我“你应该知道这一点”,我正在寻求帮助来理解这个问题。它应该计算斐波那契数列我得到了这个代码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 回答

?
梦里花落0921

TA贡献1772条经验 获得超6个赞

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


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

    }

}

它从您的输入流创建数组,然后将传递的函数应用于两个元素,将前一次迭代的结果转移到 position 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]));

    }

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


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

    }

}

它从您的输入流创建数组,然后将传递的函数应用于两个元素,将前一次迭代的结果转移到 position 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]));

    }

}


查看完整回答
反对 回复 2022-10-07
?
30秒到达战场

TA贡献1828条经验 获得超6个赞

我假设拥有超过 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并在每一步生成你拥有的元素之后的元素,将数组左移以适应新元素,并返回旧的第一个元素(它不再在数组中)。请注意,由于这有副作用(修改外部数组),它不能与.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


查看完整回答
反对 回复 2022-10-07
  • 2 回答
  • 0 关注
  • 121 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信