0

このリスト内のオブジェクトの他の値によってグループ化された、このオブジェクトの値の 1 つを集約したいオブジェクトのリストがあります。

現在、グループ化したいプロパティをハッシュキーとして使用しており、オブジェクトをトラバースしています:

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
4

2 に答える 2

2

コードで見られるいくつかの問題とは別に、1 つの解決策は (余裕があれば) GuavaEquivalenceを使用する(またはコードで複製する) ことです。を実装してコンテナとしてEquivalence<MyObject>使用します。Map<Equivalence.Wrapper<MyObject>, MyObject>3 つの文字列メンバーで等価を作成します。

これにより、この状況で壊れないようになります。

// 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);
于 2013-06-13T13:45:28.277 に答える
0

これをエレガントに解決する場合は、lambdja ライブラリ (ここからダウンロードWeb サイト) を使用できます。たとえば、次のコードを使用して列を合計できます (このリンクを参照)。

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

このライブラリを使用すると、数行で問題を解決できます。

于 2013-06-13T13:47:43.470 に答える