聚合两个以上的Java 8属性 [英] Aggregating more than two properties Java 8

查看:101
本文介绍了聚合两个以上的Java 8属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为简单起见,我有

 class Per{
    int a;
    long b;
    double c;
    String d;
}

假设我有3000个类型为Per的对象并收集在List<Per> pers

Let say I have 3000 Object of Type Per and collected in a List<Per> pers

现在我要实现:-

  • 如果object为null或dnullblank
  • ,则跳过 a b
  • c上执行的操作的合计值
  • Skip if object is null or d is null or blank
  • sum of a
  • sum of b
  • aggregated value of operation performed on c

老方法是

int totalA = 0; long totalB = 0l; long totalC = 0l;
    for (Per per : pers) {
        if (per.d != null && !per.d.trim().equals("")) {
            totalA += per.a;
            totalB += per.b;
            totalC += someOperation(per.c);
        }
    }

someOperation的实现并不重要,因为它可能很简单,也可能很复杂.

someOperation implemention is not important as it may be simple or complex.

如何通过Java8流和lambda表达式实现此目标?

How can I achieve this via Java8 streams and lambda expression?

可能的答案是这样的

int totalA = 0; long totalB=0l;
     pers.stream().filter(p->{
         if(p == null || p.d == null || p.d.trim().equals(""))
             return false;
         return true;
     }).forEach(per->{
         totalA += per.a;
            totalB += per.b;
     });

但是totalA和totalB必须是最终的或实际上是最终的

我想到的其他可能性是:

Other possibilities in my mind are:

1按建议的方式使用Supplier重用已过滤的流,然后应用映射和聚合操作.

1 re-use the filtered stream using Supplier as suggested then apply map and aggregation operations.

2收集过滤的Per,然后进行forEach

2 Collect the filtered Per and then do forEach

注意我在这里没有进行任何分组,无法创建新的Per或更新提供的对象.

NOTE I'm not doing any kind of grouping here and can't create new Per or update provided objects.

推荐答案

编写您自己的Accumulator类和自定义Collector,这是一个简单的任务.

Write your own Accumulator class and a custom Collector, then it's a simple task.

class Accumulator {
  private int a = 0;
  private long b = 0L;
  private double c = 0d;

  public void accumulate(Per p) {
    a += p.a;
    b += p.b;
    c += someOperation(p.c);
  }

  public Accumulator combine(Accumulator acc) {
    a += acc.a;
    b += acc.b;
    c += acc.c;
    return this;
  }
  // getter, hashCode, ...
}


Accumulator result = pers.stream()
    .filter(p -> p != null && p.d != null && !p.d.trim().isEmpty())
    .collect(Collector.of(Accumulator::new, Accumulator::accumulate, Accumulator::combine));

这篇关于聚合两个以上的Java 8属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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