[Java]List#removeでUnsupportedOperationException


Listの要素削除(remove)で"UnsupportedOperationException"が出てちょっとハマったのでそのときのメモです



String配列をjava.util.List型に変換するのによく利用するのがjava.util.Arraysクラスです
Arrays.asList()を使えばお手軽にList型に変換できます

String[] fruits = new String[]{"apple","orange","banana"};
List list = Arrays.asList(fruits);

List要素の削除でUnsupported OperationException例外

で、Arrays.asList()で作成したListの要素を削除するとUnsupportedOperationExceptionでエラーとなってしまいます
エラーとなるサンプル

import java.util.Arrays;
import java.util.List;
public class Test1 {
  public static void main(String[] args) {
    String[] fruits = new String[]{"apple","orange","banana"};
    List list = Arrays.asList(fruits);
    for(String fruit : list){
      if("orange".equals(fruit)){
        list.remove(fruit);
      }
    }
  }

上記コードを実行すると、以下のエラーとなります

Exception in thread "main" java.lang.UnsupportedOperationException
  at java.util.AbstractList.remove(AbstractList.java:144)
  at java.util.AbstractList$Itr.remove(AbstractList.java:360)
  at java.util.AbstractCollection.remove(AbstractCollection.java:252)
  at test.Test1.main(Test1.java:15)

UnsupportedOperationExceptionとなる理由

Java APIドキュメントには以下の様に書いてあります

public static List asList(T… a)

指定された配列に連動する固定サイズのリストを返します。返されたリストへの変更は、そのまま配列に書き込まれます。

…以下略

対処方法

UnsupportedOperationException例外が起こらない様にする為にコードを修正します
修正する箇所は、Listインスタンスを生成する部分で、以下の様に変更します

//List list = Arrays.asList(fruits);
//以下に変更
List list = new LinkedList(Arrays.asList(fruits));

これで、エラーなくremoveできます
ちなみにLinkedListのインスタンスを生成しているのは、removeのパフォーマンスが良いからです