使用reduce(3个参数)函数传递集合 - 流java 8 [英] Passing a collection using a reduce (3 parameters) function - streams java 8

查看:256
本文介绍了使用reduce(3个参数)函数传递集合 - 流java 8的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用java 8的流来计算使用前两个值的值的乘法。我想调用一个将返回数组/列表/集合的函数。我正在创建一个List并向其添加1,2。

I am trying to calculate the multiplication of a value using the previous two values using java 8's stream. I want to call a function that will return an array/list/collection. I am creating a List and adding 1,2 to it.

假设列表名称是结果。

Let's say the list name is result.

public static void main (String[] args) { 
List<Integer> result = new ArrayList<Integer>();
result.add(1);
result.add(2);
int n = 5; //n can be anything, choosing 5 for this example
res(n, result);
//print result which should be [1, 2, 2, 4, 8]
}
public static List<Integer> res(int n, List<Integer> result ) {
           result.stream()
                 .limit(n)
                 .reduce(identity, (base,index) -> base);

       //return result;
}

现在问题是尝试将结果传递到流中以保持更新使用流的新值列表。根据java教程,尽管效率低下,但它是可能的。

Now the issue is trying to try to pass result into the stream to keep updating the list with the new values using the stream. According to the java tutorials, it is possible, albeit inefficient.


如果你的reduce操作涉及向集合添加元素,那么每次你的累加器函数处理一个元素时,它会创建一个新的集合,包含低效的元素。

"If your reduce operation involves adding elements to a collection, then every time your accumulator function processes an element, it creates a new collection that includes the element, which is inefficient."

我是否需要使用可选的第三个参数BinaryOperator combiner来组合列表+结果??

Do I need to use the optional third parameter, BinaryOperator combiner, to combine the list + result??

<U> U reduce(U identity,
         BiFunction<U,? super T,U> accumulator,
         BinaryOperator<U> combiner)

简而言之;我想传递一个包含两个值的列表,并让函数找到前两个值的乘法(1,2),将其添加到列表中,并找到最后两个值的乘法(2,2),并添加它到列表中,直到流达到限制。

In short; I want to pass a list with two values and have the function find the multiplication of the first two values (1,2), add it to the list, and find the multiplication of the last two values (2,2), and add it to the list, and until the stream hits the limit.

推荐答案

看起来你正在尝试实现递归关系。 reduce 方法将一些函数应用于流中的一堆预先存在的值。你不能使用 reduce 并从reducer函数中取一个中间结果并反馈到流中,这是你需要做的才能实现的递归关系。

It looks like you're trying to implement a recurrence relation. The reduce method applies some function to a bunch of pre-existing values in the stream. You can't use reduce and take an intermediate result from the reducer function and "feed it back" into the stream, which is what you need to do in order to implement a recurrence relation.

使用流实现递归关系的方法是使用其中一个流工厂方法 Stream.generate Stream.iterate iterate 工厂似乎提出了最明显的方法。需要为每个递归函数应用保留的状态在您的示例中需要两个整数,所以不幸的是我们必须创建一个对象来为我们保存这些:

The way to implement a recurrence relation using streams is to use one of the streams factory methods Stream.generate or Stream.iterate. The iterate factory seems to suggest the most obvious approach. The state that needs to be kept for each application of the recurrence function requires two ints in your example, so unfortunately we have to create an object to hold these for us:

static class IntPair {
    final int a, b;
    IntPair(int a_, int b_) {
        a = a_; b = b_;
    }
}

使用此状态对象可以创建实现的流您想要的重复:

Using this state object you can create a stream that implements the recurrence that you want:

Stream.iterate(new IntPair(1, 2), p -> new IntPair(p.b, p.a * p.b))

一旦有了这样的流,收集价值就很简单了到列表中:

Once you have such a stream, it's a simple matter to collect the values into a list:

List<Integer> output =
    Stream.iterate(new IntPair(1, 2), p -> new IntPair(p.b, p.a * p.b))
          .limit(5)
          .map(pair -> pair.a)
          .collect(Collectors.toList());
System.out.println(output);

[1, 2, 2, 4, 8]

作为除此之外,您可以使用相同的技术生成Fibonacci序列。您所做的只是提供不同的起始值和迭代函数:

As an aside, you can use the same technique to generate the Fibonacci sequence. All you do is provide a different starting value and iteration function:

Stream.iterate(new IntPair(0, 1), p -> new IntPair(p.b, p.a + p.b))

您还可以实现类似的递归关系使用 Stream.generate 。这还需要一个帮助类。帮助程序类实现结果值的 Supplier ,但它也需要维护状态。因此它需要是可变的,这在我的书中有点粗糙。迭代函数也需要烘焙到生成器对象中。这使得它不如 IntPair 对象灵活,它可用于创建任意重复。

You could also implement a similar recurrence relation using Stream.generate. This will also require a helper class. The helper class implements Supplier of the result value but it also needs to maintain state. It thus needs to be mutable, which is kind of gross in my book. The iteration function also needs to be baked into the generator object. This makes it less flexible than the IntPair object, which can be used for creating arbitrary recurrences.

这篇关于使用reduce(3个参数)函数传递集合 - 流java 8的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆