我有这样的代码:

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


当前回答

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

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

例子:

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

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

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

parentRecepeIdList.add("555");

其他回答

这个问题已经困扰我很多次了。数组。asList创建一个不可修改的列表。 返回指定数组支持的固定大小的列表。

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

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

这将产生一些额外的垃圾,但您将能够对其进行突变。

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

对于这个问题,我有另一个解决方案:

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

工作在newList;)

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

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

例子:

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

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

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

parentRecepeIdList.add("555");

取代

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

to

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

or

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

or

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

或(更适合删除元素)

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