2011-11-12 8 views
5

コレクション内の重複するオブジェクトを見つけてマークする最良の方法は何ですか?リストの人がいるとし、重複戦略は名と姓の完全一致に基づいているとしましょう。コレクション内の重複の検索

  1. 行うための簡単な方法があり、それは

の複製であるオブジェクトを識別し、すべてが

  • マークそれが重複する各人物の重複
  • で示す各重複人を複製識別するこれはグアバ?

  • +0

    あなたは「オブジェクトにそれを特定の意味を明確にすることができあなたが最初のアイテムが「本当の」アイテムであり、後続のアイテムが重複しているということを意味すると思いますか? –

    答えて

    5

    あなたがこれを行うにはグアバは必要ありません。

    List<Person> people = ... 
    Map<Name, Person> peopleByName = new HashMap<>(); 
    for (Person person : people) { 
        // Name is a simple value class with equality based on its fields 
        Name name = new Name(person.getFirstName(), person.getLastName()); 
        Person firstPersonWithName = peopleByName.get(name); 
        if (firstPersonWithName == null) { 
        peopleByName.put(name, person); 
        } else { 
        // or whatever you do to mark a duplicate 
        person.setDuplicateOf(firstPersonWithName); 
        } 
    } 
    

    行として最初の名前を使用して...あなたの代わりにMapのグアバTableを使用してNameを作成する必要が避けることができ、言いましたキーと姓の列キーとして、例えば言う。

    もう1つの選択肢は、Multimaps.indexを使用して、リスト内のすべての人を名前で索引付けすることです。その後、特定の名前にマッピングされた人のリストごとに、最初の人物がリストの名前を持つ最初の人物になり、他の人物は重複したものになります。

    1

    personオブジェクトの.equals()をオーバーライドしないようにしてください。次に、各人物オブジェクト 'duplicateOf'などに新しいフィールドを追加します。

    次に、配列をループして、各人を他の人と照らし合わせるだけです。人物 'duplicateOf'フィールドがnullの場合、それをスキップします。 .equals()がtrueを返す場合、 'duplicateOf'フィールドを設定することができます。

    1

    クラスPersonは、boolean equals(Object o)を実装する必要があります。

    次にあなたが重複にこの方法を見つけることができます。

    あなたがどこかにいる:Collection<Person> list;

    Person[] persons = list.toArray(); 
    Integer[] duplicateOf = new Integer[persons.length]; 
    Arrays.fill(duplicateOf, -1); 
    
    // For all the values in the Collection 
    for (int i = 0; i < persons.length; i++) { 
    
        // Find the duplicate 
        for (int j = 0; j < persons.length; j++) { 
        if (persons[i].equals(persons[j]) && i != j) 
         duplicateOf[j] = i; 
        } 
    } 
    

    は今、あなたはあなたがこの方法を読むことができる配列duplicateOfを持っている:要素jの重複はインデックスでありますduplicateOf[j]

    2

    Guava's TreeMultimapを試すことができます。

    好きなようにあなたの人々を比較する比較器とそれを初期化し、新たな1 TreeMultimapを作成します。ここではTreeMultimap.create(Comparator, Ordering.arbitrary())

    は、ユニットテストです:

    package org.test.guava; 
    
    import java.util.Arrays; 
    import java.util.Comparator; 
    import java.util.List; 
    
    import org.junit.Test; 
    
    import com.google.common.collect.Multimap; 
    import com.google.common.collect.Ordering; 
    import com.google.common.collect.TreeMultimap; 
    
    public class GuavaTest { 
    
        private static class Person { 
         private String name; 
    
         public Person(String name) { 
          this.name = name; 
         } 
    
         public String getName() { 
          return name; 
         } 
    
         @Override 
         public String toString() { 
          return "Person [name=" + name + "]"; 
         } 
    
        } 
    
        @Test 
        public void test() throws Exception { 
         List<Person> persons = Arrays.asList(new Person("person1"), new Person("person2"), new Person("person1")); 
         Comparator<Person> comparator = new Comparator<Person>() { 
          public int compare(Person o1, Person o2) { 
           return o1.getName().compareTo(o2.getName()); 
          } 
         }; 
    
         Multimap<Person, Person> groups = TreeMultimap.create(comparator, Ordering.arbitrary()); 
         for(Person person : persons) { 
          groups.put(person, person); 
         } 
    
         System.out.println(groups.asMap()); 
        } 
    
    } 
    
    +0

    私の質問から3番の要件をどのように満たすことができますか? –

    +0

    回答が更新されました。マルチセットであなたを誤解して申し訳ありません。 TreeMultimapsを使用してみてください。 – szhem

    +2

    ソートされたマルチマップを使用する必要はなく、別のキーの等価性を選択する方法として使用しているため、意図が明確ではありません。名前自体をキーとして使用する方が望ましいです。それでは 'Multimaps.index'を使うだけです。 – ColinD

    関連する問題