4

次のコードを検討してください。

class A {

  private int i;

  boolean equals( Object t) {
      if (this == t)
          return true;
      if (!( t instanceof A))
          return false;
      if (this.i == t.i);
  }

}

Map<String,A> orig;
Map<String,B> dup;

私はこれをやろうとしています

orig.entrySet().removeAll(dup.entrySet());

equals メソッドが呼び出されていることがわかります。これは常に true ですか、それとも代わりに compareTo を呼び出す可能性がありますか?

4

7 に答える 7

4

はい、呼び出しますequals()。オブジェクトが含まれていることがわかっcompareTo()ている場合にのみ使用できます(たとえば、ソートされたセットはおそらくこれを行う可能性があります)。Set Comparable

于 2009-05-12T17:33:49.467 に答える
3

実装に依存します。

たとえば、 aは andHashSetを使用hashCodeequalsます。ATreeSetはおそらく を使用しますcompareTo。最終的に、型が適切に動作する限り、問題にはなりません。

于 2009-05-12T17:39:44.137 に答える
1

http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collection.html

「実装は、たとえば、最初に2つの要素のハッシュコードを比較することによって、equals呼び出しを回避する最適化を自由に実装できます。」

ほとんどの場合、equalsを使用しますが、上記のステートメントを考慮すると、equals()の呼び出しに完全に依存することはできません。equals()をオーバーライドするときは常に、hashCode()をオーバーライドすることをお勧めします。

于 2009-07-08T07:50:50.840 に答える
1

TreeSet は compareTo を使用します。これを試してください:

public class A {

    private int i;

    A(int i) {
        this.i = i;
    }

    @Override
    public boolean equals(Object t) {
        if (this == t)
            return true;
        if (!( t instanceof A))
            return false;
        return (this.i == ((A)t).i);
    }

    public static void main(String[] args) {
        List<A> remove = Arrays.asList(new A(123), new A(789));
        Set<A> set = new TreeSet<A>(new Comparator<A>() {
            @Override
            public int compare(A o1, A o2) {
                return o1.i - o2.i;  
                // return 0; // everything get removed
            }
        });
        set.add(new A(123));
        set.add(new A(456));
        set.add(new A(789));
        set.add(new A(999));

        set.removeAll(remove);
        for (A a : set) {
            System.out.println(a.i);
        }
        System.out.println("done");
    }
}

Comparator が常に 0 を返すようにすると、すべてが削除されます! Comparator を使用せずに Comparable を実装する場合も同様です。

TreeSet は、getEntry で compareTo を使用する TreeMap に基づいています。
TreeSet の Javadoc で (最終的に) 読むことができます:

... Set インターフェイスは equals 操作に関して定義されていますが、TreeSet インスタンスはその compareTo (または比較) メソッドを使用してすべての要素の比較を実行します...

[]]

于 2009-05-12T18:33:57.170 に答える
0

一部のSet実装は依存していますhashCode(例: HashSet)。そのため、オーバーライドするときは常にオーバーライドする必要がありhashCodeますequals

于 2009-05-12T17:40:51.110 に答える
0

compareTo がどこで使用されているかわかりません。Map インターフェイスの remove() の javadoc には、「より正式には、このマップに (key==null ? k==null : key.equals(k)) というようなキー k から値 v へのマッピングが含まれている場合、そのマッピングは削除されます。」Set インターフェースの場合も同様に、「より正式には、セットにそのような要素が含まれている場合、(o==null ? e==null : o.equals(e)) のような要素 e を削除します。」

removeAll() の javadoc は、それがどのように動作するかを述べていないことに注意してください。つまり、他の人が言ったように、それは実装の詳細です。

Bloch によると、Sun の Java では (私の記憶が正しければ)、コレクションを繰り返し処理し、remove() を呼び出します。

于 2009-05-12T18:12:02.027 に答える
0

私が認識しているJavaライブラリ内の実装は、これを行わない唯一の実装はIdentityHashMapです。たとえば、 TreeMapには適切な がありませんComparator

于 2009-05-12T17:43:59.310 に答える