繁体   English   中英

减少java中自定义对象的操作

[英]Reduce operation on custom object in java

如何使用Reduce操作在对象的两个字段上执行求和。

例如

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()));

好吧,如果你想在IntStream上调用IntStream

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。

第二个参数将当前Pojo元素的getA()getB()值添加到中间和。

第三个参数组合了两个部分和。

sum()方法的实现如下:

public final int sum() {
    return reduce(0, Integer::sum);
}

reduce()替换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);

有关更多信息,请参阅缩减操作段落。

与伊兰的回答几乎相同:

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];

你正在使用reduce函数是一个BinaryOperator,它有两个T对象作为参数并返回一个T对象

你想要的是这个reduce函数 ,它与累加器一起使用,以下是如何使用它(参见Eran的答案):

int sum = pojoList.stream()
                  .reduce(0 /* the identity for your binary operation, for sum this is 0 */, 
                         (s,ob)->s+ob.getA()+ob.getB() /* s is the accumulated value */,
                         Integer::sum /* combine accumulated values by sum */);
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()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM