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

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

问题描述

很简单,我有

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

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

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

现在我想实现:-

  • 如果对象为 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天全站免登陆