如何使用Reduce操作在对象的两个字段上执行求和。
e.g。
class Pojo
{
public Pojo(int a, int b) {
super();
this.a = a;
this.b = b;
}
int a ;
int b;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
}
Pojo object1 = new Pojo(1, 1);
Pojo object2 = new Pojo(2, 2);
Pojo object3 = new Pojo(3, 3);
Pojo object4 = new Pojo(4, 4);
List<Pojo> pojoList = new ArrayList<>();
pojoList.add(object1);
pojoList.add(object2);
pojoList.add(object3);
pojoList.add(object4);
我可以使用IntStream
执行求和:
int sum = pojoList.stream()
.mapToInt(ob -> (ob.getA() + ob.getB()))
.sum();
我想使用reduce 执行相同的操作,但不知怎的,我的语法不正确:
pojoList.stream()
.reduce(0, (myObject1, myObject2) -> (myObject1.getA() + myObject2.getB()));
答案 0 :(得分:12)
好吧,如果你想在IntStream
上调用reduce:
int sum = pojoList.stream()
.mapToInt(ob ->(ob.getA()+ob.getB()))
.reduce(0, (a,b)->a+b);
当然,同样适用于Stream<Integer>
:
int sum = pojoList.stream()
.map(ob ->(ob.getA()+ob.getB()))
.reduce(0, (a,b)->a+b);
或使用方法参考:
int sum = pojoList.stream()
.map(ob ->(ob.getA()+ob.getB()))
.reduce(0, Integer::sum);
或没有map()
:
int sum = pojoList.stream()
.reduce(0, (s,ob)->s+ob.getA()+ob.getB(),Integer::sum);
在最后一个例子中,我使用了变体:
<U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);
因为减少的值(Integer
)与Stream
元素的类型不同。
第一个参数是标识值 - 0。
第二个参数将当前getA()
元素的getB()
和Pojo
值添加到中间总和。
第三个参数组合了两个部分和。
答案 1 :(得分:4)
sum()
方法实现如下:
public final int sum() {
return reduce(0, Integer::sum);
}
用sum()
替换reduce()
:
int sum = pojoList.stream()
.mapToInt(ob -> (ob.getA() + ob.getB()))
.reduce(0, Integer::sum);
或者,没有mapToInt()
:
int pojoSum = pojoList.stream()
.reduce(0, (sum, ob) -> sum + ob.getA() + ob.getB(), Integer::sum);
有关详情,请参阅Reduction operations段。
答案 2 :(得分:2)
几乎与伊兰的答案相同:
int sum = pojoList.stream()
.mapToInt(ob ->(ob.getA()+ob.getB()))
.reduce(Integer::sum)
.orElse(0);
只是为了它的乐趣,你也可以使用collect
:
int result = pojoList.stream()
.collect(
() -> new int[] { 0 },
(x, y) -> x[0] = x[0] + y.getA() + y.getB(),
(left, right) -> left[0] += right[0])[0];
答案 3 :(得分:2)
reduce function you are using正在使用BinaryOperator,它将两个T对象作为参数,返回一个T对象。
你想要的是这个reduce function,它与累加器一起使用,以下是如何使用它(参见Eran的回答):
<script>
var canvas = null;
var context = null;
var imageObj = null;
window.onload = function(){
canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
imageObj = new Image();
var image = '<?php echo $filepath; ?>';
imageObj.src = image;
context.drawImage(imageObj, 0, 0);
draw();
}
function draw() {
ctx = canvas.getContext('2d');
ctx.fillStyle = "black";
for(var i = 0; i < 2; i++) {
var x = Math.random()*400;
var y = Math.random()*300;
ctx.beginPath();
ctx.arc(x , y, 2, 0, 2 * Math.PI, false);
ctx.fill();
ctx.stroke();
ctx.closePath();
}
}
</script>
答案 4 :(得分:2)
class Pojo {
static public Pojo add(Pojo p1, Pojo p2) {
return new Pojo(p1.getA() + p2.getA(), p1.getB() + p2.getB())
}
//...
}
所以稍后:
Pojo pojoSum = pojoList.stream().reduce(new Pojo(0,0), Pojo::add);
pojoSum.getA() + pojoSum.getB()