次のようなコードがあります:
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)
。