«前の日(07-21) 最新 次の日(07-23)» 追記

ヽ(´・肉・`)ノログ

2005|05|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|11|12|
2010|01|02|03|04|05|06|07|08|

2010-07-22

_ [java] Collection / Generics まとめ

今日はコレクションをやりました.良く使う割にはあんまり知らないことがあったなぁ

20100722研修

collection

java collection framework
  • List
    • ArrayList
    • LinkedList
  • Set (null なし)
    • HashSet
  • Map (null あり)
    • HashMap
  • SortedMap 順序ありMap
    • TreeMap
  • SortedSet 順序ありSet
    • TreeSet
Comparator と Comparable

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()); という風に使う.

Comparable
このオブジェクト自身を比較できますよという印
Comparator
比較するためのオブジェクトですよという印
equals / hashCode

Object にある public method.変える時は適切にオーバーライドする.

equals

意味として等しいか?を示す.

たとえば,50円が2つ入っているリストを持つオブジェクトと,100円が1つ入っているリストを持つオブジェクトは等しいか?

  • 金額という観点から => 50*2=100 だから等しい
  • 種類という観点から => 50 と 100 だから異なる

そのオブジェクトをどういう風に使いたいかによって,「等しさ」は異なる.使う人間が定義してやらないといけない.

オマケ 同値(等しさ)の定理は以下の3つ

  • X=X
  • X=Y なら Y=X
  • X=Y Y=Z なら X=Z
hashCode
public int hashCode()

つまり,無限に存在するオブジェクトを,int数だけの有限空間に無理矢理突っこむという関数.異なるオブジェクトが同じhashCodeを返してもいい.やらないし,やらないほうがいいけど

public int hashCode(){
    return 0;
}

とか定数も禁止されてはいない.↑でやったMapやSetに値を入れる時のキーなどに使う.


generics

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でコンパイルしてもちゃんと動く)のためにそうなっている.

extends / super
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の親ならを何でも入れられるリストを作れる.でも〜の親ってあんまり宣言する機会がない.

[]

«前の日(07-21) 最新 次の日(07-23)» 追記