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

我当前正在使用要分组的属性作为哈希键,并且正在遍历对象,因此:

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's Equivalence(或在代码中复制它)。您将实现Equivalence<MyObject>并将Map<Equivalence.Wrapper<MyObject>, MyObject>用作容器;您将对三个字符串成员进行等效处理。

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

// Oops! Same key...
s1 = "foo", s2 = "bar", s3 = "baz"
s1 = "fooba", s2 = "rb", s3 = "az"


另外,您可以使用地图的.put()方法的返回值(旧值):

MyObject holder = map.put(key, ungrouped);
if (holder != null)
    holder.setNumericProp(etc);

09-10 07:29