为什么Java流映射将我的结果减少两次? [英] Why does Java stream map reduce count my result twice?

查看:76
本文介绍了为什么Java流映射将我的结果减少两次?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

        ComparisonResults comparisonResults = requestsList
                .stream()
                .map(item -> getResponse(item))
                .map(item -> compareToBl(item))
                .reduce(new ComparisonResults(), (result1, result2) ->
                {
                     result1.addSingleResult(result2);
                 //   return result1;
                    return new ComparisonResults(result1);
                });

和此代码b:

        ComparisonResults comparisonResults = requestsList
                .parallelStream()
                .map(item -> getResponse(item))
                .map(item -> compareToBl(item))
                .reduce(new ComparisonResults(), (result1, result2) ->
                {
                     result1.addSingleResult(result2);
                 //   return result1;
                    return new ComparisonResults(result1);
                });

我要做的就是创建响应对象,然后将它们转换为comaprisonResult对象,并将其简化为一个comaprisonResult.

代码a显示了正确的int类成员comparisonResults.num_of_sub_responses==5

代码b显示一个int类成员comparisonResults.num_of_sub_responses==10,它是正确结果的两倍.

java 8 reduce应该是线程安全的,对吧?

我错过了什么吗?

getResponsecompareToBl是线程安全的

解决方案

您正在突变reduce中的传入对象.这是错误的.修改传入的对象后 创建新对象并没有帮助.

您想做的是

.collect(ComparisonResults::new, ComparisonResults::addSingleResult,
         (a,b)->/* code to merge two ComparisonResults instances*/);

如果.map(item -> compareToBl(item))的结果为ComparisonResults,或者说addSingleResult合并两个ComparisonResults实例,则可以将ComparisonResults::addSingleResult用作合并函数,尽管它的名称有点误导./p>

您应该仔细阅读文档中的减少"一章及其后续部分可变减少".

I have this code a:

        ComparisonResults comparisonResults = requestsList
                .stream()
                .map(item -> getResponse(item))
                .map(item -> compareToBl(item))
                .reduce(new ComparisonResults(), (result1, result2) ->
                {
                     result1.addSingleResult(result2);
                 //   return result1;
                    return new ComparisonResults(result1);
                });

and this code b:

        ComparisonResults comparisonResults = requestsList
                .parallelStream()
                .map(item -> getResponse(item))
                .map(item -> compareToBl(item))
                .reduce(new ComparisonResults(), (result1, result2) ->
                {
                     result1.addSingleResult(result2);
                 //   return result1;
                    return new ComparisonResults(result1);
                });

All I do is to create response objects, then transform them to comaprisonResult objects and to reduce them to one comaprisonResult.

code a shows an int class member comparisonResults.num_of_sub_responses==5 which is correct

code b shows an int class member comparisonResults.num_of_sub_responses==10 which is double the correct result.

java 8 reduce should be thread safe, right?

am i missing anything?

getResponse and compareToBl are thread safe

解决方案

Your are mutating an incoming object in reduce. This is wrong. It doesn’t help that you are creating a new object after modifying the incoming object.

What you want to do, is

.collect(ComparisonResults::new, ComparisonResults::addSingleResult,
         (a,b)->/* code to merge two ComparisonResults instances*/);

If the result of .map(item -> compareToBl(item)) is ComparisonResults or, in other words, addSingleResult merges two ComparisonResults instances, you can use ComparisonResults::addSingleResult as merge function, though it’s name is a bit misleading then.

You should carefully read the "Reduction" chapter of the documentation and its follow-up, "Mutable reduction".

这篇关于为什么Java流映射将我的结果减少两次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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