6

重複の可能性:
Map.get(Object key) が (完全に) ジェネリックではない理由は
何ですか Java の TreeSet<E> remove(Object) が E を取らないのはなぜですか

ここで HashSet が引数の型を E に制限しないのはなぜですか:

public boolean contains(Object o)
public boolean remove(Object o)

add() の場合と同様

public boolean add(E e)

つまり、コンパイラがタイプ E のオブジェクトのみが追加されることを強制している場合、セットは他のタイプを含む/削除することはできません

4

4 に答える 4

4

違いは、コレクションの整合性を維持するために追加はタイプ セーフでなければならないのに対し、項目のチェック/削除は、コレクションのタイプ セーフを損なうリスクなしに「タイプを許容」する余裕があることです。つまり、間違ったタイプの要素を追加すると、セットは無効になります。一方、間違った型の要素の存在をチェックすると、単純に a が返されますfalse。にも同じことがremove言えます: 互換性のない型の要素を渡すと、それはセット+に含まれないため、削除はノーオペレーションになります。


+型消去を悪用するハックによって入れない限り。

于 2012-10-09T20:20:03.750 に答える
2

containsandのパラメータをremove制限するEことはできません。なぜなら、それらに等しいオブジェクトを与えることができるはずだからです。これは非常に便利です。より正確には、の API は次のようにHashSet.remove述べています。

... より正式には、(o==null ? e==null : o.equals(e)) のような要素 e を削除します (このセットにそのような要素が含まれている場合)。

Object.equalsこれはObject、異なるタイプ間の同等性を有効にするのにも非常に役立ちます。

containsしたがって、 andのより一般的な機能を有効にするにはremove(オブジェクト ID のみではなく等価クラスで)、それらをObjectパラメーターとして使用する必要があります。


例:

    HashSet<ArrayList<String>> set = new HashSet<ArrayList<String>>();
    ArrayList<String> list = new ArrayList<String>();
    list.add("foo");
    LinkedList<String> equalList = new LinkedList<String>();
    equalList.add("foo");
    set.add(list);

    System.out.println(list.equals(equalList)); // prints: true
    System.out.println(set.contains(equalList)); // prints: true

    System.out.println(set); // prints: [[foo]]
    set.remove(equalList);
    System.out.println(set); // prints: [[]]
于 2012-10-09T21:00:13.113 に答える
2

その場合、セットは他のタイプを含む/削除することはできません

もちろんできます。タイプ消去について読むかHashSet<E>、非ジェネリックにキャストしてHashSet、タイプではないオブジェクトを追加Eしてください。

このコードをチェックしてください:

Integer testInt = new Integer(3);

// First, create a generic set of strings
HashSet<String> set = new HashSet<String>();
set.add("abc");

// Then make it non-generic and add an integer to it
((HashSet) set).add(testInt);

// Now your set-of-strings contains an integer!
System.out.println(set); // prints: [abc, 3]

// Remove the integer
set.remove(testInt);
System.out.println(set); // prints: [abc]

この奇妙さの理由は、ジェネリック型の情報が実行時に消去され、セットがオブジェクトの単純なセットになるためです。

于 2012-10-09T20:19:07.160 に答える
0

これら 2 つのメソッドを使用してセットに何も追加していないため、型パラメーターを制約する必要はありません。タイプが一致しない場合、メソッドは false を返すだけです。

于 2012-10-09T20:19:18.157 に答える