なぜなJava Collectionsの削除方法を汎?
-
01-07-2019 - |
質問
なぜな 収集します。remove(Object o) 薬?
のように思わ Collection<E>
可 boolean remove(E o);
その後、誤ってみremove(例えば) Set<String>
ではなく個々の文字列から Collection<String>
, でコンパイル時にエラーの代わりにデバッグの問題です。
解決
ジブロッホのですが、ピューを参照してこの問題に Java Puzzlers IV:の ファントム参照を脅威攻撃のクローン、の復讐 シフト.
ジブロッホと(6:41)というgenerifyの取得方法 の地図の除去方法及びその他のもの"ではないたします。
多数の合理的なプログラムできなかったgenerified場合
だけの汎用タイプのコレクションパラメータのタイプです。例えとして取り扱わなければならな交差点の List
の Number
s
List
の Long
s.
他のヒント
remove()
( Map
など Collection
な汎用が対応することができるでしょうパス如何なる型のオブジェクト remove()
.のオブジェクトを除去しなくてと同じタイプのオブジェクトに渡ししますので remove()
;を求めているのみな同じになります。からの仕様 remove()
, remove(o)
オブジェクトを削除し e
その (o==null ? e==null : o.equals(e))
は true
.場合がありますので注意しても必要 o
や e
同じタイプです。このから、以下のようなもの equals()
メソッドは、 Object
パラメータとしてだけでなく、同じタイプとしてのオブジェクトです。
が、一般的にtrueになると多くのクラス equals()
定義によりそのオブジェクトのみと同等物の固有のクラスは確かない人もいます。例えば、仕様 List.equals()
という二つのリストオブジェクトが等しい場合はその両方のリストと同じ内容を持っている場合であっても、異なる実装 List
.ならばこの問いを持つことは可能ですが、 Map<ArrayList, Something>
るために呼 remove()
と LinkedList
引数として与えた場合、それはできるだけ除去することが望のキリストは同じ内容です。このことはできない場合 remove()
た汎用的に制限された引数タイプです。
かご型のパラメータをワイルドカードは使用できなくな汎用の除去方法。
感覚走ること地図のget(Object)メソッド.の"get"メソッドの場合な汎用いるべき合理的に見渡すオブジェクトと同じ型の型パラメータとします。そして、現場パスを回しながらマップワイルドカードとして最初の型パラメータが無くなってもいいの要素にマップする方法、その引数がクラスを提供します。.ワイルドカード引数で本当に満足することで、コンパイラができないことを保タイプに通知するものとします。この理由を追加する、またはこれに類するい期待を保証するのが正しい追加する前にもするものと期待される。しかし、取り外しの際、オブジェクトの場合、型が不正確ではな戦います。そうでない場合は、引数を現したワイルドカードの方法で利用できなくなにもできるオブジェクトができることを保証に属する集いつでも参照がなくなってしばらくすると前線....
ょうかは説明できないもうですが、論理的に十分でした。
また、その他の回答にあたれる理由の一つの方法は受け入れ Object
, である述語.考え、以下のサンプル
class Person {
public String name;
// override equals()
}
class Employee extends Person {
public String company;
// override equals()
}
class Developer extends Employee {
public int yearsOfExperience;
// override equals()
}
class Test {
public static void main(String[] args) {
Collection<? extends Person> people = new ArrayList<Employee>();
// ...
// to remove the first employee with a specific name:
people.remove(new Person(someName1));
// to remove the first developer that matches some criteria:
people.remove(new Developer(someName2, someCompany, 10));
// to remove the first employee who is either
// a developer or an employee of someCompany:
people.remove(new Object() {
public boolean equals(Object employee) {
return employee instanceof Developer
|| ((Employee) employee).company.equals(someCompany);
}});
}
}
このオブジェクトに渡される remove
法責任者を定義する equals
方法。ビル述語が非常に簡単なことです。
いつのコレクションの Cat
, 一部のオブジェクト参照の種類 Animal
, Cat
, SiameseCat
, は、 Dog
.いのかどうかのオブジェクトと呼ばれている Cat
または SiameseCat
参考えます。るかどうかも含まれのオブジェクトと呼ばれている Animal
参考えぁいますが、残念ながら完璧にリーズナブル。のオブジェクトが、す Cat
, やが表示されます。
更にある場合でも、オブジェクトが含まれるもの以外のもの Cat
, が問題ないかどうかが表示されコレクションに--だ"と回答していますか?".の"ルックアップ-スタイル"コレクションの一部のようにするべきであるが有意義に受け入れ基準のスーパータイプを判断するものと、オブジェクトが存在するのです。場合に渡されたオブジェクト参照は無関係なタイプがありませんの回収可能性を含むこのクエリでもない有意義であることを伝えてください必ず答えは"no").しかし、がんを制限するパラメータをサブタイプはsupertypesで最も実用的な受け入れず、答えは"no"、anyオブジェクトタイプをクライアントとは無関係なのです。
いったことでremove()理由は無いケアをどのようなオブジェクトお願いしますで十分に関わらず、そのオブジェクトのものが収録されることもあるので通話equals()のものです。このチェックが必要タイプにadd()になっていないかご確認くだけが含まれます物体のパターンを示すことが分かった。
削除しない汎用的な方法で、既存コードを用いた汎用コレクションがコンパイルがそのまま残されていますが同じ行動です。
見 http://www.ibm.com/developerworks/java/library/j-jtp01255.html ます。
編集:一番迷惑そのaddメソッドはクラスを提供します。.[...削除私の説明...]質問の回答から何を学べるか"というテーマfirebird84りました。
ことができます。ここで例示する
public interface A {}
public interface B {}
public class MyClass implements A, B {}
public static void main(String[] args) {
Collection<A> collection = new ArrayList<>();
MyClass item = new MyClass();
collection.add(item); // works fine
B b = item; // valid
collection.remove(b); /* It works because the remove method accepts an Object. If it was generic, this would not work */
}
でも、既存の前Java5)のコードです。例えば、
Set stringSet = new HashSet();
// do some stuff...
Object o = "foobar";
stringSet.remove(o);
今だと言われるかもしれませんが、上記のコードが間違っているのは、もうoら異種のオブジェクト(すなわち、含まれる文字列番号、物体ます。削除したいすべての試合では、法律で取り除だけを無視し、非文字列と聞いていた不平等なものとする。だがremove(String o)がなくなります。