Why do I get an UnsupportedOperationException when trying to remove an element from a List?
我有这个代码:
1 2 3 4 5 6 7 8 9 |
我明白了:
1 2 | 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) |
号
这是怎么正确的方法?爪哇.15
您的代码有很多问题:
返回固定大小列表从API:
Arrays.asList : Returns a fixed-size list backed by the specified array.
号
你不能用它来对付它;你不能用它来对付它。您不能在结构上修改
创建一个
1 |
。关于
从API:
String.split(String regex) : Splits this string around matches of the given regular expression.
号
EDCOX1·18是一个正则表达式元;如果你想在一个EDCOX1的文本18中分离,你必须将它转至EDCOX1×20,这是一个Java字符串文字是EDCOX1,21。
修复:1 | template.split("\\|") |
。关于更好的算法
与其一次调用一个随机索引的
有了这个,您的算法将是
这个把我烧了很多次。
创建具有相同内容的新列表:
1 |
这将产生一点额外的垃圾,但您将能够对其进行变异。
可能是因为您使用的是不可修改的包装器。
更改此行:
1 |
到此行:
1 |
号
我认为替换:
1 |
具有
1 |
。
解决问题。
arrays.as list()返回一个不允许操作影响其大小的列表(请注意,这与"不可修改"不同)。
你可以做
您想从列表中删除
更新:如下面所述,此算法仅在元素无序时才有意义,例如,如果列表代表一个包。另一方面,如果列表有一个有意义的顺序,这个算法就不会保留它(相反,Polygene润滑剂的算法会保留它)。
更新2:所以回顾一下,一个更好的(线性的,保持顺序的,但是有O(N)随机数)算法应该是这样的:
1 2 3 4 5 6 7 8 9 10 11 | LinkedList<String> elements = ...; //to avoid the slow ArrayList.remove() int k = elements.size() - count; //elements to select/delete int remaining = elements.size(); //elements remaining to be iterated for (Iterator i = elements.iterator(); k > 0 && i.hasNext(); remaining--) { i.next(); if (random.nextInt(remaining) < k) { //or (random.nextDouble() < (double)k/remaining) i.remove(); k--; } } |
只需阅读aslist方法的javadoc:
Returns a {@code List} of the objects
in the specified array. The size of
the {@code List} cannot be modified,
i.e. adding and removing are
unsupported, but the elements can be
set. Setting an element modifies the
underlying array.
号
这是来自Java 6,但它看起来与Android Java是一样的。
编辑
结果列表的类型是
。
我有另一个解决办法:
1 2 |
号
在
是的,在
除了使用链表外,只需使用
例子:
1 2 3 4 5 6 7 |
号
当您尝试对不允许的托收执行某些操作时,就会出现这种不受支持的操作异常;在您的情况下,当您调用
更换
1 |
号
到
1 2 |
或
1 |
。
或
1 |
或(更适合于删除元素)
1 |
。
下面是来自数组的代码片段
1 2 3 4 5 6 7 8 9 10 11 12 | public static <T> List<T> asList(T... a) { return new ArrayList<>(a); } /** * @serial include */ private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable { private static final long serialVersionUID = -2764017481108945198L; private final E[] a; |
所以,当调用aslist方法时,它会返回它自己的私有静态类版本的列表,这个版本不会覆盖从abstractlist向数组中存储元素的add funcion。所以默认情况下,在抽象列表中添加方法会引发异常。
所以它不是常规的数组列表。
不能删除,也不能添加到固定大小的数组列表中。
但您可以从该列表创建子列表。
江户十一〔30〕
1 2 3 4 5 6 7 8 9 | 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 = list.subList(0, list.size() - (list.size() - count)); } return StringUtils.join(list,","); } |
*另一种方法是
1 |
。
这将创建arraylist,其大小与arrays.aslist不同。
使用这个
。
在