2016-11-24 3 views
2

私はオブジェクトの大きなリストを2つの属性でグループ化しようとしています。私が何を意味するかを実証するために、次の例を考えてみましょう。1回の反復で2つの属性でオブジェクトのリストをグループ化するにはどうすればよいですか?

public class Foo { 

    private String attributeA; 
    private String attributeB; 
    private String anotherAttribute; 
} 

私はグループに属性attributeAattributeBによってFooオブジェクトの大規模なリストが欲しいです。現在私は以下のことをしています。

List<Foo> foos = getFoos(); 
Map<Set<String>, List<String>> groupedFoos = Sets.newHashMap(); 
Set<String> fooGroup; 
for(Foo foo : foos) { 
    fooGroup = Sets.newHashMap(foo.getAttributeA(), foo.getAttributeB()); 

    if (!groupedFoos.containsKey(fooGroup)) { 
     groupedFoos.put(fooGroup, Lists.newArrayList(foo)); 
    } else { 
     groupedFoos.get(fooGroup).add(foo); 
    } 
} 

どのように私はMap<Set<String>, List<String>>ようMapを使用せずに同じ結果を達成することができますか?これを1回の繰り返しで行うことが重要です。属性attributeAattributeBの値を入れ替えることができます。したがってをMapのキーとして使用することもできません。

+1

ようCollectors.groupingBy()メソッドを使用していることを使用します地図のキー?あるいは単に 'Sets.newHashMap()'を使用して、属性をあらかじめソートしてください。 –

+0

また、ハッシュコードをオーバーライドすることもできません。この場合、エンティティを変更することはできません。私は彼らにアクセスできないので。 – Javiator

+0

@maraca私はソートしたくない、私はちょうど2つのパラメータでグループ化したい。 – Javiator

答えて

2

Mapをキーにしたい場合は、いつでも両方の属性を比較する方法で自分自身のKeyを書くことができます。

public class Key { 
    private String a; 
    private String b; 
    private String c; 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o == null || getClass() != o.getClass()) return false; 

     Key foo = (Key) o; 

     if (a.equals(foo.a) || a.equals(foo.b)) { 
      return true; 
     } 

     return b.equals(foo.b) || b.equals(foo.a); 
    } 

    @Override 
    public int hashCode() { 
     int result = a.hashCode(); 
     result = 31 * result + b.hashCode(); 
     return result; 
    } 
} 
1

クラスにキーメソッドを追加します。あなたがJava8を使用できる場合は、 `Foo.hashCode`を上書きすることができた場合は

public class Foo { 

    private String attributeA; 
    private String attributeB; 
    private String anotherAttribute; 

    public final String getKey() { 
     return this.attributeA + "$" + this.attributeB; //use $ or any other delimiter as suggested in the comment 
    } 
} 

その後、両方の属性のソート組み合わせをハッシュそれを実装していない理由を以下

final Map<String, List<Foo>> result = getFoos().stream().collect(Collectors.groupingBy(Foo:getKey)); 
+0

あなたの答えをありがとう、私の質問で述べたように:属性の値を交換することができます。 – Javiator

+0

にはデリミタが必要です。 (12,3)と(1、23)は、同じキーを与えます。 @Javiatorが最初に注文します。 – maraca

+0

@maracaあなたは正しい、答えは編集:) – Mitchapp

関連する問題