[英]Aggregating value from java ArrayList in an elegant way
我有一个对象列表,我想要聚合此对象的一个值,这些值按此列表中对象的其他值分组。
我正在使用我想要分组的属性作为哈希键,我正在遍历对象,所以:
ArrayList<MyObject> raw = Some Data;
Map<String, MyObject> map = new HashMap<String, MyObject>();
for (MyObject ungrouped : raw) {
String key = ungrouped.getStringOne().getName() + ungrouped.getStringTwo() + ungrouped.getStringThree();
if (map.containsKey(key)){
MyObject holder = map.get(key);
holder.setNumericProp(holder.getNumericProp() + ungrouped.getNumericProp());
// map.put(key, holder); //Edited after comments
}
else{
map.put(key, ungrouped);
}
}
return map.values().toArray(new MyObject[map.values().size()]);
如果不使用串联字符串作为键,有更优雅的方法吗?
如果这是SQL(我从几个应用程序层开始),它将是:
SELECT SUM(numericvalue) FROM sometable GROUP BY stringone, stringtwo , stringthree
除了我在代码中看到的一些问题,一个解决方案是使用(如果你能负担得起) Guava的Equivalence
(或在你的代码中复制它)。 您将实现Equivalence<MyObject>
并使用Map<Equivalence.Wrapper<MyObject>, MyObject>
作为容器; 你在三个字符串成员上做了等价。
这样就不会在这种情况下破坏:
// Oops! Same key...
s1 = "foo", s2 = "bar", s3 = "baz"
s1 = "fooba", s2 = "rb", s3 = "az"
此外,您可以使用map的.put()
方法的返回值(旧值):
MyObject holder = map.put(key, ungrouped);
if (holder != null)
holder.setNumericProp(etc);
如果您正在优雅地解决这个问题,您可以使用lambdja库( 在此下载 , 网站 )。 例如,您可以使用以下代码对列进行SUM化( 查看此链接 ):
double sum = sumFrom(select(sales,
having(on(Sale.class).getBuyer().isMale())
.and( having(on(Sale.class).getSeller().isMale())))).getCost();
你也可以用这个分组( 看看这个链接 ):
Group<Person> group = group(meAndMyFriends, by(on(Person.class).getAge()));
使用这些库,您可以在几行中解决您的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.