以下色々なサイトで既出なのですが、自戒を込めて書いておこう(-_-;
仕事で書いてたプログラムですが、よくある「リストをループでまわして要素を削除する」処理で少しハマってました。実行時にjava.lang.UnsupportedOperationExceptionで落ちるっていう。
まず「リストをループでまわして要素を削除する」処理についてJavaで標準的なのって何だろと調べた所、StackOverflowにありました。
Calling remove in foreach loop in Java
結構評価あるのでiterator使うのが良いみたい。
以下はブログ用に簡単なコードにしてみました。
まずは普通に成功するパターン。
package arrayloopremove;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ArrayLoopRemove {
public static void main(String[] args) {
List<String> meiboList = new ArrayList<>();
meiboList.add("堀北真希");
meiboList.add("能年玲奈");
meiboList.add("宮崎あおい");
System.out.println("remove前 -> " + meiboList);
Iterator<String> i = meiboList.iterator();
while(i.hasNext()){
String name = i.next();
if(!name.startsWith("堀北")){
i.remove();
}
}
System.out.println("remove後 -> " + meiboList);
}
}
実行結果
remove前 -> [堀北真希, 能年玲奈, 宮崎あおい]
remove後 -> [堀北真希]
これを以下のように書いてました(^^;
最初のリスト定義が違うだけで、それ以降は上記と同じコードです。
package arrayloopremove;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class ArrayLoopRemove {
public static void main(String[] args) {
List<String> meiboList = Arrays.asList("堀北真希", "能年玲奈", "宮崎あおい");
System.out.println("remove前 -> " + meiboList);
Iterator<String> i = meiboList.iterator();
while(i.hasNext()){
String name = i.next();
if(!name.startsWith("堀北")){
i.remove();
}
}
System.out.println("remove後 -> " + meiboList);
}
}
実行結果
remove前 -> [堀北真希, 能年玲奈, 宮崎あおい]
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.remove(AbstractList.java:161)
at java.util.AbstractList$Itr.remove(AbstractList.java:374)
at arrayloopremove.ArrayLoopRemove.main(ArrayLoopRemove.java:39)
Java Result: 1
えー、なんでダメなの?なぞだー、とハマってた(^^;
原因は最初にあげた参考元の以下ブログに書いてあります。
悪あがきプログラマー - String配列から指定要素を削除する。
で、以下ならいける。地味にハマったなぁ。
package arrayloopremove;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class ArrayLoopRemove {
public static void main(String[] args) {
List<String> meiboList = new ArrayList<>();
meiboList.addAll(Arrays.asList("堀北真希", "能年玲奈", "宮崎あおい"));
System.out.println("remove前 -> " + meiboList);
Iterator<String> i = meiboList.iterator();
while(i.hasNext()){
String name = i.next();
if(!name.startsWith("堀北")){
i.remove();
}
}
System.out.println("remove後 -> " + meiboList);
}
}