聚合两个以上的属性 Java 8 [英] Aggregating more than two properties 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 或
d
为null
或blank
则跳过 a
的总和b
的总和- 在
c
上执行的操作的聚合值
- Skip if object is null or
d
isnull
orblank
- 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屋!