sort (3)

今までのまとめ。パフォーマンスのために複雑さを犠牲にした狂気の沙汰言語JavaC++もよく分からないが、GCと文字列クラスによりC++よりだいぶマシなのだと思う。C#との比較は気になるところ。

  • 配列は要素数が固定となるが、使用メモリが少ない。
  • ArrayListのtoString()メソッドは、java.util.AbstractCollectionクラスでオーバーライドされている。
  • Listの複数要素での初期化は、List L = Arrays.asList("a", "c", "b")のようにできる。配列は、String[] L = {"a", "c", "b"}のようにできる。
  • ArrayListから配列は、toArray()メソッドで変換できる。配列からList(ArrayListでなくList)は、java.util.Arrays.asList()スタティックメソッドで変換できる。
  • 配列から変換したListは、元の配列の値を変更するとListの値も変更される。逆にListの値を変更すると配列の値も変更される。Listの要素を追加しようとすると元の配列の個数は変更できないので例外が発生。
  • ArrayListから配列に変換するメソッドは、Object toArray()、 T toArray(T[] a)の2つがあるが、後者のルールは結構複雑。前者の方は正直使い道がよく分からなかった。返値はビューでなくコピーを返す。
  • 配列はtoString()メソッドがjava.lang.Object.toString()をオーバーライドしていないのでループでまわして取り出す必要がある。
  • "-Xlint:unchecked"オプション警告が出たのは、J2SE 5.0でコレクションフレームワークAPIが変更になっているのに、従来の1.4の記述方法のままなので、警告が出されてたということらしい。"-source 1.4 -target 1.4"オプションを付ければ警告は出ないらしい。
  • ArrayListもしくは全てのベースクラスでsort()メソッドを持っていない。
  • ソートするには以下のメソッドを使用。配列は、java.util.Arrays.sort()スタティックメソッド。コレクションは、java.util.Collections.sort()スタティックメソッド。
  • Pythonのsorted()つまりコピーに対してソートするには、恐らく一括では不可能でコピーしてからソートすることになる。その際、java.util.ArrayList.clone()メソッドを使用するが、Object[] clone()なので、Genericsを使用しても結局キャストが必要になる。
  • 複数の要素を持つリスト同士を直接比較は恐らくできないのでJavaではDSUはできない。

ワイルドカードを使ったイミュータブル

色々検索していたら、ワイルドカードを使ったイミュータブルという面白そうな話題を見つけた。以下で紹介されている本は、洋書の『Java Generics And Collections』という本みたいだが結構面白そう。

import java.util.*;

class test {
    public static void main(String[] args) {
        List<Integer> L = Arrays.asList(1, 2, 3);
        L.add(4);
    }
}

/* 実行結果 */
>java test
Exception in thread "main" java.lang.UnsupportedOperationException
        at java.util.AbstractList.add(AbstractList.java:131)
        at java.util.AbstractList.add(AbstractList.java:91)
        at test.main(test.java:6)

上記の記事ではわざわざワイルドカードを使うことによってイミュータブルを実現しているらしいが、上のサンプルコードではL.add(4)でエラー。工夫しなくてもイミュータブルになっている。asList()のAPIリファレンスを読むと「指定された配列に連動する固定サイズのリストを返します」と書いてある。バージョンが6.0から変更になったのだろうか?