今日はコレクションをやりました.良く使う割にはあんまり知らないことがあったなぁ
Comparable は interface で int compareTo(T obj) というメソッドを持っている.1,2,3とかa,b,cとか自然な順序を比較することができるというinterface.compareToで自分自身と比べる.Comparator も interface だけど,int compare(T obj1, T obj2) という風に,2つのオブジェクトを比較するためのインターフェース.Arrays.sort(someList, new SomeComparator()); という風に使う.
Object にある public method.変える時は適切にオーバーライドする.
意味として等しいか?を示す.
たとえば,50円が2つ入っているリストを持つオブジェクトと,100円が1つ入っているリストを持つオブジェクトは等しいか?
そのオブジェクトをどういう風に使いたいかによって,「等しさ」は異なる.使う人間が定義してやらないといけない.
オマケ 同値(等しさ)の定理は以下の3つ
public int hashCode()
つまり,無限に存在するオブジェクトを,int数だけの有限空間に無理矢理突っこむという関数.異なるオブジェクトが同じhashCodeを返してもいい.やらないし,やらないほうがいいけど
public int hashCode(){
return 0;
}
とか定数も禁止されてはいない.↑でやったMapやSetに値を入れる時のキーなどに使う.
1.5から導入された.1.4以前だと
List list = new ArrayList();
list.add("A");
list.add(new Integer(100));
String s = (String) list.get(0);
みたいに書かないといけない.
という理由から,「あるリストに決められたオブジェクトしか入れられない」と決めて,取るときのキャストを不要にした書き方を用意した.それがジェネリクス.こんなの
List<String> list = new ArrayList<String>();
コンパイルの時.
コンパイルした後のバイトコードにはジェネリクスの情報は入っていない(イレイジャー erasure).後方互換性(1.4でコンパイルできるものが1.5でコンパイルしてもちゃんと動く)のためにそうなっている.
List<Number> list = new ArrayList<Number>(); list.add(new Integer(100)); // できない
はコンパイルエラーになる.なぜか?「IntegerはNumberではない」から.ジェネリクスでは普通にやるとオブジェクトの継承関係を見てはくれない.
不便すぎるので,ワイルドカードを用意した
List<?> list = new ArrayList<Object>();
で何でも入れられるリストになる.
でもそれだと1.4と同じ状態になってしまうので,条件つきのワイルドカードを用意した
List<? extends Number> list = new ArrayList<Number>(); list.add(new Integer(100)); // できる!!
これで「Number型を持つもの」をリストに入れられる.同様に <? super T> でTの親ならを何でも入れられるリストを作れる.でも〜の親ってあんまり宣言する機会がない.