Why do I get an UnsupportedOperationException when trying to remove an element from a List?

后端 未结 17 1963
后悔当初
后悔当初 2020-11-22 07:43

I have this code:

public static String SelectRandomFromTemplate(String template,int count) {
   String[] split = template.split(\"|\");
   List         


        
相关标签:
17条回答
  • 2020-11-22 07:48

    The list returned by Arrays.asList() might be immutable. Could you try

    List<String> list = new ArrayList(Arrays.asList(split));
    
    0 讨论(0)
  • 2020-11-22 07:51

    I've got another solution for that problem:

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

    work on newList ;)

    0 讨论(0)
  • 2020-11-22 07:52

    This one has burned me many times. Arrays.asList creates an unmodifiable list. From the Javadoc: Returns a fixed-size list backed by the specified array.

    Create a new list with the same content:

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

    This will create a little extra garbage, but you will be able to mutate it.

    0 讨论(0)
  • 2020-11-22 07:53

    Arrays.asList() returns a list that doesn't allow operations affecting its size (note that this is not the same as "unmodifiable").

    You could do new ArrayList<String>(Arrays.asList(split)); to create a real copy, but seeing what you are trying to do, here is an additional suggestion (you have a O(n^2) algorithm right below that).

    You want to remove list.size() - count (lets call this k) random elements from the list. Just pick as many random elements and swap them to the end k positions of the list, then delete that whole range (e.g. using subList() and clear() on that). That would turn it to a lean and mean O(n) algorithm (O(k) is more precise).

    Update: As noted below, this algorithm only makes sense if the elements are unordered, e.g. if the List represents a Bag. If, on the other hand, the List has a meaningful order, this algorithm would not preserve it (polygenelubricants' algorithm instead would).

    Update 2: So in retrospect, a better (linear, maintaining order, but with O(n) random numbers) algorithm would be something like this:

    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--;
      }
    }
    
    0 讨论(0)
  • 2020-11-22 07:54

    Arraylist narraylist=Arrays.asList(); // Returns immutable arraylist To make it mutable solution would be: Arraylist narraylist=new ArrayList(Arrays.asList());

    0 讨论(0)
  • 2020-11-22 07:54

    The issue is you're creating a List using Arrays.asList() method with fixed Length meaning that

    Since the returned List is a fixed-size List, we can’t add/remove elements.

    See the below block of code that I am using

    This iteration will give an Exception Since it is an iteration list Created by asList() so remove and add are not possible, it is a fixed array

    List<String> words = Arrays.asList("pen", "pencil", "sky", "blue", "sky", "dog"); 
    for (String word : words) {
        if ("sky".equals(word)) {
            words.remove(word);
        }
    }   
    

    This will work fine since we are taking a new ArrayList we can perform modifications while iterating

    List<String> words1 = new ArrayList<String>(Arrays.asList("pen", "pencil", "sky", "blue", "sky", "dog"));
    for (String word : words) {
        if ("sky".equals(word)) {
            words.remove(word);
        }
    }
    
    0 讨论(0)
提交回复
热议问题