代码之家  ›  专栏  ›  技术社区  ›  Niraj Sonawane

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

  •  16
  • Niraj Sonawane  · 技术社区  · 6 年前

    如何使用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()));
    
    5 回复  |  直到 6 年前
        1
  •  14
  •   Eran    6 年前

    如果你想在 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);
    

    由于降低值(an Integer )与 Stream 元素。

    第一个参数是标识值-0。

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

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

        2
  •  4
  •   Oleksandr Pyrohov Andreas    6 年前

    sum() 方法实现如下:

    public final int sum() {
        return reduce(0, Integer::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 段落

        3
  •  2
  •   kutschkem    6 年前

    这个 reduce function you are using 是采用BinaryOperator,它采用两个T对象作为参数 返回T对象

    你想要的是这个 reduce function ,它与累加器一起工作,下面是如何使用它(参见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 */);
    
        4
  •  2
  •   RoberMP    6 年前

    与Eran的回答几乎相同:

    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];
    
        5
  •  2
  •   Eugene    6 年前
    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()