1. はじめに
先日、toshi0383さんの Java - Arrays.asList の罠 という記事を拝見しました。
Arrays.asList は、プリミティブ型の配列をリスト化してくれない。
という問題についてでして、非常に参考になりました。
今回はもう一つ罠について、投稿させて頂きます。
2. java.util.Arrays.asList(T ...a); とは?
配列からコレクションを生成する場合に使用するメソッドで、こんな風に使います。
// 配列を作成
String[] array = {"foo","bar","baz"};
// Listに変換
List<String> list = Arrays.asList(array);
そのままStreamも生成できるので便利
Arrays.asList(array).stream().forEach(s -> {
// 処理
});;
3. 問題
Listを生成してくれるので、当然こんな書き方をすると思います。
// List生成
List<String> list = Arrays.asList("a", "b", "c");
// 要素を追加
list.add("d");
// 要素を削除
list.remove(0);
3.1 java.lang.UnsupportedOperationException
しかし、実行すると下記例外が発生します。
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at qiita.Recursion.main(Test.java:11)
4. 原因
原因は、JavaのAPI仕様書に記載されていました。
修飾子と型 | メソッドと説明 |
---|---|
static,List | asList(T... a) 指定された配列に連動する固定サイズのリストを返します。 |
4.1 固定サイズのリストとは?
Arrays.asList() で作成されるListのオブジェクトは、
元配列からのコピーではなく。
変換前の配列をあたかもListのように見せているだけ、なので元配列の要素数を変換しようとすると、前述のUnsupportedOperationExceptiongaが発生します。
4.2 使えないメソッド
つまり、Arrays.asList() で生成したListオブジェクトは以下の操作を受け付けないという事になります。
修飾子と型 | メソッドと説明 |
---|---|
void |
add(int index, E element) このリスト内の指定された位置に、指定された要素を挿入します(オプションの操作)。 |
E |
remove(int index) このリスト内の指定された位置にある要素を削除します(オプションの操作)。 |
void |
clear() すべての要素をこのリストから削除します(オプションの操作)。 |
5. まとめ
Arrays.asList() で生成したListのオブジェクトは、要素数の変更をするListのメソッドの操作を受け付けません。
toshi0383さん、勝手に記事リンク張らせて頂きました。すみません。
参考
http://qiita.com/toshi0383/items/87abe2a8e08df1180a6e
http://docs.oracle.com/javase/jp/8/api/
http://www.atmarkit.co.jp/ait/articles/0408/24/news095.html
http://namihira.hatenablog.com/entry/2015/03/31/231929