问题描述
我有以下代码:
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应该是线程安全的,对吧?
我错过了什么吗?
getResponse
和compareToBl
是线程安全的
您正在突变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流映射将我的结果减少两次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!