我有这样的代码:

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


当前回答

Arrays.asList()返回一个不允许操作影响其大小的列表(注意,这与“不可修改”不同)。

你可以写new ArrayList<String>(Arrays.asList(split));来创建一个真正的副本,但看到你正在尝试做什么,这里有一个额外的建议(你有一个O(n²)算法在下面)。

你想从列表中删除list.size() - count(我们称之为k)随机元素。只是选择尽可能多的随机元素,并将它们交换到列表的最后k个位置,然后删除整个范围(例如使用subList()和clear())。这将把它变成一个精简和平均O(n)算法(O(k)更精确)。

更新:如下所述,这个算法只在元素是无序的情况下才有意义,例如,如果List表示一个Bag。另一方面,如果List具有有意义的顺序,则该算法不会保留它(polygeneluants的算法会保留它)。

更新2:所以回想起来,一个更好的(线性,保持顺序,但有O(n)个随机数)算法应该是这样的:

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--;
  }
}

其他回答

Arrays.asList()在内部使用固定大小的数组。 你不能动态地添加或删除thisArrays.asList()

使用这个

Arraylist<String> narraylist=new ArrayList(Arrays.asList());

在naraylist中,您可以轻松地添加或删除项目。

Arrays.asList()返回的列表可能是不可变的。你能试试吗?

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

以下是来自Arrays的代码片段

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函数来将元素存储在数组中。默认情况下,抽象列表中的add方法会抛出异常。

所以它不是正则数组列表。

这个UnsupportedOperationException会在你试图对集合执行一些不允许的操作时出现,在你的情况下,当你调用数组时。asList不返回java.util.ArrayList。它返回一个java.util。数组$ArrayList是一个不可变列表。你不能向它添加,也不能从它删除。

是的,在数组上。返回一个固定大小的列表。

除了使用链表,只需使用addAll方法列表。

例子:

String idList = "123,222,333,444";

List<String> parentRecepeIdList = new ArrayList<String>();

parentRecepeIdList.addAll(Arrays.asList(idList.split(","))); 

parentRecepeIdList.add("555");