10

実装可能な特定の基準に従って、コレクション内の重複するエントリを見つけるためのツールまたはライブラリはありますか?


明確にするために、特定の基準に従ってエントリを相互に比較したいと考えています。だから私はPredicate戻ってくるだけで十分だと思いtrueます。false


使えませんequals

4

7 に答える 7

7

基準のセマンティックに依存します。

基準が特定のクラスに対して常に同じであり、基本的な概念に固有のものである場合は、セットを実装equalshashCodeて使用するだけです。

基準がコンテキストに依存する場合 org.apache.commons.collections.CollectionUtils.select(java.util.Collection, org.apache.commons.collections.Predicate)が適切なソリューションになる可能性があります。

于 2012-05-25T14:00:28.350 に答える
4

重複を削除するだけでなく、重複を見つけたい場合は、Collection を配列にスローし、条件を実装する Comparator を介して配列を並べ替えてから、配列を直線的にたどって隣接する重複を探す方法があります。

ここにスケッチがあります(テストされていません):

   MyComparator myComparator = new MyComparator();
   MyType[] myArray = myList.toArray();
   Arrays.sort( myArray, myComparator );
   for ( int i = 1; i < myArray.length; ++i ) {
      if ( 0 == myComparator.compare( myArray[i - 1], myArray[i] )) {
         // Found a duplicate!
      }
   }

編集:コメントから、重複があるかどうかを知りたいだけです。上記のアプローチはこれにも有効です。ただし、カスタム Comparator を使用して java.util.SortedSet を簡単に作成することもできます。ここにスケッチがあります:

   MyComparator myComparator = new MyComparator();
   TreeSet treeSet = new TreeSet( myComparator );
   treeSet.addAll( myCollection );
   boolean containsDuplicates = (treeSet.size() != myCollection.size()); 
于 2012-05-25T14:08:59.717 に答える
3

任意のタイプのオブジェクト間の重複を検索するように Java セットを適合させることができます。基準に基づいて同等性を評価するプライベート ラッパーでターゲット クラスをラップし、ラッパーのセットを構築します。

以下は、テクニックを説明するやや長い例です。同じ名を持つ 2 人は等しいと見なされるため、5 つのオブジェクトの配列で 3 つの重複が検出されます。

import java.util.*;
import java.lang.*;

class Main {
    static class Person {
        private String first;
        private String last;
        public String getFirst() {return first;}
        public String getLast() {return last;}
        public Person(String f, String l) {
            first = f;
            last = l;
        }
        public String toString() {
            return first+" "+last;
        }
    }
    public static void main (String[] args) throws java.lang.Exception {
        List<Person> people = new ArrayList<Person>();
        people.add(new Person("John", "Smith"));
        people.add(new Person("John", "Scott"));
        people.add(new Person("Jack", "First"));
        people.add(new Person("John", "Walker"));
        people.add(new Person("Jack", "Black"));
        Set<Object> seen = new HashSet<Object>();
        for (Person p : people) {
            final Person thisPerson = p;
            class Wrap {
                public int hashCode() { return thisPerson.getFirst().hashCode(); }
                public boolean equals(Object o) {
                    Wrap other = (Wrap)o;
                    return other.wrapped().getFirst().equals(thisPerson.getFirst());
                }
                public Person wrapped() { return thisPerson; }
            };
            Wrap wrap = new Wrap();
            if (seen.add(wrap)) {
                System.out.println(p + " is new");
            } else {
                System.out.println(p + " is a duplicate");
            }
        }
    }
}

この例は ideone [リンク]で試すことができます。

于 2012-05-25T14:11:20.713 に答える
2

.NETIEqualityComparer<T>のインターフェイスに似た新しいインターフェイスを作成しました。

このようなEqualityComparator<T>Iは、重複を検出する次のメソッドに渡されます。

public static <T> boolean hasDuplicates(Collection<T> collection,
        EqualsComparator<T> equalsComparator) {
    List<T> list = new ArrayList<>(collection);
    for (int i = 0; i < list.size(); i++) {
        T object1 = list.get(i);
        for (int j = (i + 1); j < list.size(); j++) {
            T object2 = list.get(j);
            if (object1 == object2
                    || equalsComparator.equals(object1, object2)) {
                return true;
            }
        }
    }
    return false;
}

このようにして、ニーズに合わせて比較をカスタマイズできます。

于 2012-05-29T19:13:36.227 に答える
2

マップを使用して、コレクションを反復処理しながら要素をマップに配置し(述語がキーを形成します)、既にエントリがある場合は重複を見つけました。

詳細については、こちらを参照してください:コレクション内の重複の検索

于 2012-05-25T14:00:19.147 に答える
0

Treeset を使用すると、これを簡単に行うことができます。

Set uniqueItems = new TreeSet<>(yourComparator);
List<?> duplicates = objects.stream().filter(o -> !uniqueItems.add(o)).collect(Collectors.toList());

yourComaratorを呼び出すときに使用されuniqueItems.add(o)、アイテムがセットに追加されtrue、アイテムが一意である場合に返されます。コンパレーターがアイテムを重複していると見なした場合は、add(o)false を返します。

これが機能するには、項目のメソッドが TreeSet のドキュメントに従ってequals一致している必要があることに注意してください。yourComarator

于 2017-07-17T13:36:50.840 に答える
-2

重複を含む を繰り返し、ArrayListに追加しますHashSet。add メソッドが false を返すとHashSet、複製がコンソールに記録されます。

于 2015-03-07T17:44:47.627 に答える