Почему я получаю UnsupportedOperationException при попытке удалить элемент из списка?

Мой последний запрос включил несколько ответов здесь, которые помогли - объединить группу по, count & amp; GROUP_CONCAT.

SELECT GROUP_CONCAT(id), `magento_simple`, COUNT(*) c 
FROM product_variant 
GROUP BY `magento_simple` HAVING c > 1;

Это обеспечивает идентификатор обоих примеров (разделенных запятыми), нужного мне штрих-кода и количества дубликатов.

Соответственно изменить таблицу и столбцы.

421
задан Pang 10 May 2017 в 06:11
поделиться

8 ответов

Довольно много проблем с вашим кодом:

На Массивы.asList , возвращающий список фиксированного размера

Из API:

Arrays.asList : возвращает список фиксированного размера , поддерживаемый указанным массивом.

Вы не можете добавить к нему ; вы не можете удалить из него . Вы не можете структурно изменить список List .

Исправление

Создайте LinkedList , который поддерживает более быстрое удаление .

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

На split с использованием регулярного выражения

Из API:

String.split (String regex) : разбивает эту строку вокруг совпадений с заданным регулярным выражением .

| - метасимвол регулярного выражения; если вы хотите разбить литерал | , вы должны экранировать его до \ | , который в качестве строкового литерала Java имеет вид «\\ |» .

Исправление:

template.split("\\|")

В лучшем алгоритме

Вместо вызова remove по одному со случайными индексами, лучше сгенерировать достаточное количество случайных чисел в диапазоне, а затем просмотреть Перечислите один раз с помощью listIterator () , вызвав remove () по соответствующим индексам. По stackoverflow есть вопросы о том, как генерировать случайные, но различные числа в заданном диапазоне.

При этом ваш алгоритм будет O (N) .

943
ответ дан 22 November 2019 в 23:09
поделиться

Создание нового списка и заполнение допустимых значений в новом списке работали на меня.

Код, бросающий ошибку -

List<String> list = new ArrayList<>();
   for (String s: list) {
     if(s is null or blank) {
        list.remove(s);
     }
   }
desiredObject.setValue(list);

После, фиксируют -

 List<String> list = new ArrayList<>();
 List<String> newList= new ArrayList<>();
 for (String s: list) {
   if(s is null or blank) {
      continue;
   }
   newList.add(s);
 }
 desiredObject.setValue(newList);
0
ответ дан 22 November 2019 в 23:09
поделиться

Arrays.asList () возвращает список, который не позволяет выполнять операции, влияющие на его размер (обратите внимание, что это не то же самое, что «неизменяемый»).

Вы можете сделать new ArrayList (Arrays.asList (split)); , чтобы создать настоящую копию, но, видя, что вы пытаетесь сделать, есть дополнительное предложение (у вас есть Алгоритм O (n ^ 2) прямо под этим).

Вы хотите удалить list.size () - count (давайте назовем это k ) случайных элементов из списка. Просто выберите столько случайных элементов и поменяйте их местами в конечные k позиции списка, затем удалите весь этот диапазон (например, используя для этого subList () и clear ()). Это превратило бы его в скудный и средний алгоритм O (n) ( O (k) более точен).

Обновление : как указано ниже, этот алгоритм имеет смысл только в том случае, если элементы неупорядочены, например если список представляет собой сумку. Если, с другой стороны, список имеет значимый порядок, этот алгоритм не сохранит его (вместо этого будет действовать алгоритм полигенных смазочных материалов).

Обновление 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--;
  }
}
4
ответ дан 22 November 2019 в 23:09
поделиться

Просто прочтите JavaDoc для метода asList:

Возвращает {@code List} объектов в указанном массиве. Размер {@code List} нельзя изменить, т.е. добавление и удаление не поддерживается, но элементы могут быть установленный. Установка элемента изменяет базовый массив.

Это из Java 6, но похоже, что это то же самое для java для Android.

РЕДАКТИРОВАТЬ

Тип результирующего списка - Arrays.ArrayList , который является частным классом внутри Arrays.class. Фактически, это не что иное, как представление списка для массива, который вы передали с помощью Arrays.asList . Как следствие: если вы измените массив, список тоже изменится. А поскольку размер массива нельзя изменить, операция удаления и добавления должна не поддерживаться.

4
ответ дан 22 November 2019 в 23:09
поделиться

Это исключение UnsupportedOperationException возникает, когда вы пытаетесь выполнить некоторую операцию над коллекцией, где это не разрешено, и в вашем случае, когда вы вызываете Arrays.asList , он не возвращает java.util.ArrayList . Он возвращает java.util.Arrays $ ArrayList , который является неизменяемым списком. Вы не можете добавить к нему и не можете удалить его.

2
ответ дан 22 November 2019 в 23:09
поделиться

Вероятно, потому что вы работаете с неизменяемой оболочкой .

Измените эту строку:

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

на эту строку:

List<String> list = new LinkedList<>(Arrays.asList(split));
48
ответ дан 22 November 2019 в 23:09
поделиться

Список, возвращаемый Arrays.asList () , может быть неизменяемым. Не могли бы вы попробовать

List<String> list = new ArrayList(Arrays.asList(split));
5
ответ дан 22 November 2019 в 23:09
поделиться

Этот меня много раз сжигал. Arrays.asList создает неизменяемый список. Из документации Javadoc: возвращает список фиксированного размера , поддерживаемый указанным массивом.

Создайте новый список с тем же содержанием:

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

Это создаст немного лишнего мусора, но вы сможете его видоизменить.

133
ответ дан 22 November 2019 в 23:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: