Quantcast
Viewing all articles
Browse latest Browse all 757

【Java】配列をArrayListに変換する ※注意あり

配列をArrayListに変換する方法と注意点・落とし穴

配列をArrayListに変換する方法を紹介します。
絶対にハマる落とし穴があるので、最後まで読んでください!

ListToArray.java
String[]array={"A","B","C"};List<String>list=Arrays.asList(array);System.out.println("配列 = "+Arrays.toString(array));System.out.println("List = "+list.toString());

結果

配列 = [A, B, C]
List = [A, B, C]

できた!簡単じゃん。

・・・でも

要素を追加してみる

ListToArray.java
//中略List<String>list=Arrays.asList(array);list.add("D");//Dを追加!

結果

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.add(AbstractList.java:148)
    at java.util.AbstractList.add(AbstractList.java:108)
    at codeSample.ListToArray.main(ListToArray.java:13)

エラーになる

なぜか

返すクラスを取得してみる

ListToArray.java
//中略List<String>list=Arrays.asList(array);ArrayList<String>arrayList=newArrayList<String>();System.out.println("通常のArrayList = "+arrayList.getClass());System.out.println("配列からの変換 = "+list.getClass());

結果

通常のArrayList = class java.util.ArrayList
配列からの変換 = class java.util.Arrays$ArrayList

ん、なんか違う!

深堀してみる

java.util.Arrays.class
//中略publicstatic<T>List<T>asList(T...a){returnnewArrayList<>(a);}privatestaticclassArrayList<E>extendsAbstractList<E>implementsRandomAccess,java.io.Serializable{privatestaticfinallongserialVersionUID=-2764017481108945198L;privatefinalE[]a;// ←←←finalになってる!ArrayList(E[]array){a=Objects.requireNonNull(array);// 参照コピー(追記)}@Overridepublicintsize(){returna.length;}//中略}

Arraysクラスの内部クラスに定義された簡易版のArrayListを返していた!
※E[] aには元の配列が参照コピーされる。 (追記
addメソッドの定義がなく、AbstractList.add(E e)にいくため、UnsupportedOperationExceptionが発生していた。

java.util.AbstractList.class
publicbooleanadd(Ee){add(size(),e);returntrue;}//中略publicvoidadd(intindex,Eelement){thrownewUnsupportedOperationException();}

修正

ListToArray.java
//中略ArrayList<String>arrayList=newArrayList<String>(Arrays.asList(array));arrayList.add("D");System.out.println("配列 = "+Arrays.toString(array));System.out.println("List = "+arrayList.toString());

新しくArrayListの領域をnewして変換する。 (追記

結果

配列 = [A, B, C]
List = [A, B, C, D]

Arrays.asList()は型変換するだけで、参照先メモリ領域もそのままということですね。 (追記


Viewing all articles
Browse latest Browse all 757

Trending Articles