以优雅的方式从java ArrayList聚合值

以优雅的方式从java ArrayList聚合值,java,Java,我有一个对象列表,我想将此对象的一个值与此列表中对象的其他值进行分组 我目前正在使用我想要分组的属性作为散列键,并且我正在遍历对象,以便: ArrayList<MyObject> raw = Some Data; Map<String, MyObject> map = new HashMap<String, MyObject>(); for (MyObject ungrouped : raw) { String key = ungrouped.getSt

我有一个对象列表,我想将此对象的一个值与此列表中对象的其他值进行分组

我目前正在使用我想要分组的属性作为散列键,并且我正在遍历对象,以便:

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

除了我在代码中看到的一些问题之外,一个解决方案是使用(如果您负担得起的话)(或者在代码中复制)。您将实现
等价
,并使用
映射
作为容器;在三个字符串成员上进行等价

这将使其在这种情况下不会中断:

// Oops! Same key...
s1 = "foo", s2 = "bar", s3 = "baz"
s1 = "fooba", s2 = "rb", s3 = "az"
此外,还可以使用映射的
.put()
方法的返回值(旧值):


如果您看起来优雅地解决了这个问题,那么可以使用lambdja库(,)。例如,可以使用以下代码()对列求和:

您还可以使用以下()进行分组:

groupgroup=Group(meansmyfriends,by)(on(Person.class.getAge());

有了这些库,您只需几行就可以解决问题。

map.put(key,holder);另外,你在移动的过程中改变列表中的对象,这真的是你的意图吗??我有点怀疑!我并不想让它们变异,但我需要在某个地方进行求和。我想这将使用它找到的第一个对象(带有组合键)作为保存总数的对象。为什么不使用一个整数作为值呢?因为调用方方法需要以MyObject数组的形式格式化的对象。现在,它们不再有一个长长的对象列表,而是返回一个包含聚合属性的对象短列表。这显然比在它们之间添加分隔符更优雅。但我仍在努力避免在项目中使用更多的库。番石榴似乎值得。就个人而言,我建议你使用番石榴;)<代码>等价性只是它的优点之一。
// Oops! Same key...
s1 = "foo", s2 = "bar", s3 = "baz"
s1 = "fooba", s2 = "rb", s3 = "az"
MyObject holder = map.put(key, ungrouped);
if (holder != null)
    holder.setNumericProp(etc);
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()));