リストから要素を削除しようとすると、UnsupportedOperationException が発生するのはなぜですか? 質問する

リストから要素を削除しようとすると、UnsupportedOperationException が発生するのはなぜですか? 質問する

次のようなコードがあります:

public static String SelectRandomFromTemplate(String template,int count) {
   String[] split = template.split("|");
   List<String> list=Arrays.asList(split);
   Random r = new Random();
   while( list.size() > count ) {
      list.remove(r.nextInt(list.size()));
   }
   return StringUtils.join(list, ", ");
}

私はこれを理解します:

06-03 15:05:29.614: ERROR/AndroidRuntime(7737): java.lang.UnsupportedOperationException
06-03 15:05:29.614: ERROR/AndroidRuntime(7737):     at java.util.AbstractList.remove(AbstractList.java:645)

これは正しい方法でしょうか? Java.15

ベストアンサー1

コードにはかなりの問題があります:

Arrays.asList固定サイズのリストを返す場合

APIから:

Arrays.asList:指定された配列を基にした固定サイズのリストを返します。

にすることもadd、そこから取得することもできませんremove。 を構造的に変更することはできませんList

修理

LinkedListより高速な をサポートする を作成しますremove

List<String> list = new LinkedList<String>(Arrays.asList(split));

split正規表現の取得について

APIから:

String.split(String regex): この文字列を指定された文字列の前後で分割します正規表現

|は正規表現のメタ文字です。リテラル で分割する場合は|、 にエスケープする必要があります\|。Java 文字列リテラルとしては です"\\|"

修理:

template.split("\\|")

より良いアルゴリズムについて

removeランダムなインデックスで を 1 つずつ呼び出すのではなく、範囲内で十分な数の乱数を生成し、 で を 1 回走査して適切なインデックスでを呼び出す方が適切です。stackoverflow には、指定された範囲内でランダムListでありながら異なる数値を生成する方法に関する質問があります。listIterator()remove()

これにより、アルゴリズムは次のようになりますO(N)

おすすめ記事