0

java.util.SetAPI の状態:

セットには、e1.equals(e2) のような要素 e1 と e2 のペアが含まれていません

しかし、私が理解している限りでは、e1 と e2 が重複しているかどうかを判断するためにTreeSet使用されます。Comparable/Comparator何か不足していますか?

4

3 に答える 3

5

compareToが一貫している場合(どちらである必要があります)、TreeSet が同等性を使用するかどうかを決定するかequalsどうかは問題ではありません。JavaDoc から:compareToequals

Set インタフェースを正しく実装するためには、(明示的なコンパレータが提供されているかどうかに関係なく) セットによって維持される順序付けが equals と一致している必要があることに注意してください。(equals との整合性の正確な定義については、Comparable または Comparator を参照してください。) これは、Set インターフェースが equals 操作に関して定義されているためですが、TreeSet インスタンスはその compareTo (または比較) メソッドを使用してすべての要素の比較を実行するためです。この方法で等しいと見なされる要素は、セットの観点からは等しいです。セットの動作は、その順序付けが equals と一致しない場合でも明確に定義されています。Set インターフェースの一般的な契約に従わないだけです。

equalsこのプログラムは、常に false を返しますが、'true' を出力します。しかし、バグは と が A に対して矛盾しているという事実にcompareToありequals、TreeSet のバグではありません。

class A implements Comparable<A> {
    public int compareTo(A a) {
        return 0;
    }

    public boolean equals(Object other) {
        return false;
    }

    public static void main(String[] args) {
        TreeSet<A> set = new TreeSet<A>();
        set.add(new A());
        System.out.println(set.contains(new A()));
    }
}
于 2012-11-24T12:34:08.657 に答える
0

あなたの仮定は間違っています。TreeSetは、e1がe2と等しいかどうかを判断するためにComparable/Comparatorを使用しません。EqualsメソッドはObjectクラスの一部であり、コレクションの2つの要素が同じかどうかを判断するために使用されます。すなわちe1.equals(e2)

ただし、Comparable /コンパレータインターフェイスは、要素が他の要素よりも大きいか、等しいか、または小さいかを判断するために使用されます。そして、これはソート中に使用されます。したがって、確認する必要があるのは、equalsメソッドとcomparetoメソッドが一貫していることだけです。

したがって、2つのオブジェクトを比較するには、equalsメソッドが使用され、ソート中にコンパレータ/comparableが使用されます。

編集 以下は、JDK6のメソッド定義です。AbstractSetのメソッドと同じです。TreeSetはAbstractSetを拡張します

    public boolean equals(Object obj)
    {
    if(obj == this)
        return true;
    if(!(obj instanceof Set))
        return false;
    Collection collection = (Collection)obj;
    if(collection.size() != size())
        return false;
    try
    {
        return containsAll(collection);
    }
    catch(ClassCastException classcastexception)
    {
        return false;
    }
    catch(NullPointerException nullpointerexception)
    {
        return false;
    }
    }

http://docs.oracle.com/javase/6/docs/api/java/util/AbstractSet.html

于 2012-11-24T13:05:39.537 に答える
0

TreeSetコンパレータを使用します。マップを使用して実際に要素を維持していることをご存知ですか。

 public TreeSet() {
    this(new TreeMap<E,Object>());
 }

あなたが言ったように、セットにはe1.equals(e2)のような要素e1とe2のペアは含まれていません。そのため、コンパレータにはequalsメソッドがあります。

どのように使用するかに関係Setなく、それはに依存しComparatorます。独自のコンパレータを使用する場合は、として使用できますが、通常は使用SetListません。独自のオブジェクトを追加する場合は、初期化時にTreeSet渡す必要があります。または、オブジェクトを次の方法で実装する必要があります。ComparatorTreeSetComparable

比較可能
他のオブジェクトと自分自身を比較する機能を持つ比較可能なオブジェクト

コンパレータ
2つの異なるオブジェクトを比較するために使用されます。

public int compare(Employee o1, Employee o2) {
    // if sort by name
    return o1.getName().compareTo(o2.getName());
 }


 public boolean equals(Object obj) {
        // equals with ID
        Employee e = (Employee)obj;
        return this.getId().equals(e.getId());
 }

これがJavaSorting:ComparatorvsComparableチュートリアルです。

于 2012-11-24T13:07:20.883 に答える