为什么在尝试从列表中删除元素时出现“不支持的操作异常”?

2022-08-31 04:15:55

我有这个代码:

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:返回由指定数组支持的固定大小的列表

你不能去它;你不能从它。您无法在结构上修改 .addremoveList

修复

创建一个 ,它支持更快的 。LinkedListremove

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

关于服用正则表达式split

从 API:

String.split(String regex):围绕给定正则表达式的匹配项拆分此字符串。

|是一个正则表达式元字符;如果要对文本进行拆分,则必须将其转义为 ,作为 Java 字符串文本是 。|\|"\\|"

修复:

template.split("\\|")

关于更好的算法

与其使用随机索引一次调用一个,不如在范围内生成足够的随机数,然后使用 调用适当的索引,遍历一次。关于堆栈溢出,存在有关如何在给定范围内生成随机但不同的数字的问题。removeListlistIterator()remove()

这样,您的算法将是 .O(N)


答案 2

这个已经烧了我很多次了。 创建不可修改的列表。来自 Javadoc:返回由指定数组支持的固定大小的列表。Arrays.asList

创建具有相同内容的新列表:

newList.addAll(Arrays.asList(newArray));

这将产生一些额外的垃圾,但你将能够改变它。