use*_*140 6 java java-8 java-stream
我试图使用java 8的流来计算使用前两个值的值的乘法.我想调用一个返回数组/列表/集合的函数.我正在创建一个List并向其添加1,2.
假设列表名称是结果.
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;
}
Run Code Online (Sandbox Code Playgroud)
现在问题是尝试将结果传递到流中以使用流继续使用新值更新列表.根据java教程,尽管效率低下,但它是可能的.
"如果你的reduce操作涉及向集合添加元素,那么每次你的累加器函数处理一个元素时,它都会创建一个包含该元素的新集合,这是低效的."
我是否需要使用可选的第三个参数BinaryOperator组合来组合列表+结果?
<U> U reduce(U identity,
BiFunction<U,? super T,U> accumulator,
BinaryOperator<U> combiner)
Run Code Online (Sandbox Code Playgroud)
简而言之; 我想传递一个包含两个值的列表,并让函数找到前两个值的乘法(1,2),将其添加到列表中,并找到最后两个值的乘法(2,2),并添加它到列表中,直到流达到限制.
Stu*_*rks 11
看起来你正试图实现一个递归关系.该reduce方法将一些函数应用于流中的一组预先存在的值.您不能使用reduce和从reducer函数中获取中间结果并将其"反馈"到流中,这是您为实现递归关系所需要执行的操作.
使用流实现递归关系的方法是使用其中一个流工厂方法Stream.generate或Stream.iterate.该iterate工厂似乎表明最明显的方法.对于递归函数的每个应用程序需要保留的状态在您的示例中需要两个整数,所以不幸的是我们必须创建一个对象来为我们保存这些:
static class IntPair {
final int a, b;
IntPair(int a_, int b_) {
a = a_; b = b_;
}
}
Run Code Online (Sandbox Code Playgroud)
使用此状态对象,您可以创建实现所需重复的流:
Stream.iterate(new IntPair(1, 2), p -> new IntPair(p.b, p.a * p.b))
Run Code Online (Sandbox Code Playgroud)
一旦有了这样的流,将值集合到列表中是一件简单的事情:
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]
Run Code Online (Sandbox Code Playgroud)
另外,您可以使用相同的技术生成Fibonacci序列.您所做的就是提供不同的起始值和迭代函数:
Stream.iterate(new IntPair(0, 1), p -> new IntPair(p.b, p.a + p.b))
Run Code Online (Sandbox Code Playgroud)
您还可以使用实现类似的递归关系Stream.generate.这还需要一个帮助类.辅助类实现Supplier结果值,但它也需要维护状态.因此它需要是可变的,这在我的书中有点粗糙.迭代函数也需要烘焙到生成器对象中.这使得它不如IntPair对象灵活,可以用于创建任意重复.
| 归档时间: |
|
| 查看次数: |
2425 次 |
| 最近记录: |