【问题标题】:Aggregating more than two properties Java 8聚合两个以上的属性 Java 8
【发布时间】:2017-06-28 21:39:01
【问题描述】:

很简单,我有

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

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

现在我想实现:-

  • 如果对象为空或dnullblank,则跳过
  • a 的总和
  • b 的总和
  • 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 的实现并不重要,因为它可能很简单也可能很复杂。

如何通过 Java8 流和 lambda 表达式实现这一点?

可能的答案是这样的

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 必须是最终的或有效的最终

我认为的其他可能性是:

1 使用Supplier 作为suggested 重新使用过滤后的流,然后应用映射和聚合操作。

2 收集过滤后的Per 然后做forEach

注意,我没有在此处进行任何类型的分组,也无法创建新的 Per 或更新提供的对象。

【问题讨论】:

  • 您无法创建新的 Per 对象的原因是什么?因为如果可以的话,reduce 方法可能真的很有用

标签: lambda java-8 sum field aggregate


【解决方案1】:

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

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

【讨论】:

  • 有一种方法可以在过滤器中使用Predicate((Predicate<Per>) Objects::nonNull).and(per -> Objects.nonNull(per.d).and(p -> p.d.trim().isEmpty()))
  • @AntonBalaniuc 你是对的,但是写p != null 比目标类型转换更简洁。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-10
  • 1970-01-01
  • 1970-01-01
  • 2021-06-08
  • 1970-01-01
  • 2014-12-01
相关资源
最近更新 更多