是否有可能只迭代一次流并执行2个或更多操作? [英] Is it possible to iterate a stream only once and perform 2 or more operations?

查看:189
本文介绍了是否有可能只迭代一次流并执行2个或更多操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定代码

 列表< Integer> numbers = Arrays.asList(2,4,3); $($,$,$,$,$,$,$,$,$)$ sum $ total $ $(1,(x,y) - > x * y); 
int multiplyTotal = numbers.stream()。

是否可以在迭代流时执行两个操作?



另外,请注意,每个reduce都有不同的标识:-3和1.

解决方案

创建一个自定义的类,并使用可变的缩减:

  public static void main(String [] args){
列表与LT;整数> numbers = Arrays.asList(2,4,3);

result result = numbers.stream()。collect(Result :: new,Result :: consume,Result :: combine);
System.out.println(result =+ result);
}

private static class结果{
private int sum = 0;
private int product = 1;

public void consume(int i){
sum + = i + 3;
product * = i;
}

public void combine(Result r){
// READ
sum + = r.sum + 3;
产品* = r.product;
}

@Override
public String toString(){
returnResult {+
sum =+ sum +
,product =+ product +
'}';
}
}

但是我怀疑你这样做会获得很多收益只需迭代两次就可以了。



编辑:



请注意,上面的combine()在使用并行流时调用将产生与顺序流不一致的结果。 Holger在评论中提到,这个问题是由于操作不尊重缩减的身份前提条件引起的:应用任何具有身份的值V的减少应该产生V,但是它产生V + 3以0作为身份。



确保不要使用并行流来计算结果。


Given the code

List<Integer> numbers = Arrays.asList(2, 4, 3);

int sumTotal = numbers.stream().reduce(-3, (x, y) -> x + y + 3);
int multiplyTotal = numbers.stream().reduce(1, (x, y) -> x * y);

Is it possible to perform both operations while iterating the stream only once?

Also, notice each reduce has a different identity: -3 and 1.

解决方案

You can create a custom class, and use a mutable reduction:

public static void main(String[] args) {
    List<Integer> numbers = Arrays.asList(2, 4, 3);

    Result result = numbers.stream().collect(Result::new, Result::consume, Result::combine);
    System.out.println("result = " + result);
}

private static class Result {
    private int sum = 0;
    private int product = 1;

    public void consume(int i) {
        sum += i + 3;
        product *= i;
    }

    public void combine(Result r) {
        // READ note below
        sum += r.sum + 3;
        product *= r.product;
    }

    @Override
    public String toString() {
        return "Result{" +
            "sum=" + sum +
            ", product=" + product +
            '}';
    }
}

But I doubt you will gain much by doing that over simply iterating twice as you're doing.

EDIT:

Note that the combine() method above, invoked when using a parallel stream, will produce results that are inconsistent with a sequential stream. The problem is caused, as Holger mentions in the comments, by the fact that the operation doesn't respect the identity preconditions of a reduction: applying the reduction on any value V with the identity is supposed to produce V, but it produces V + 3 with 0 as identity.

Make sure not to use a parallel stream to compute that result.

这篇关于是否有可能只迭代一次流并执行2个或更多操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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