Java List.add() UnsupportedOperationException
Я пытаюсь добавить объекты к экземпляру List<String>
, но он выдает UnsupportedOperationException
.
Кто-нибудь знает, почему?
Мой код Java:
String[] membersArray = request.getParameterValues('members');
List<String> membersList = Arrays.asList(membersArray);
for (String member : membersList) {
Person person = Dao.findByName(member);
List<String> seeAlso;
seeAlso = person.getSeeAlso();
if (!seeAlso.contains(groupDn)){
seeAlso.add(groupDn);
person.setSeeAlso(seeAlso);
}
}
Сообщение об ошибке:
java.lang.UnsupportedOperationException
java.util.AbstractList.add(Unknown Source)
java.util.AbstractList.add(Unknown Source)
javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
Ответы
Ответ 1
Не каждая реализация List
поддерживает метод add()
.
Одним из распространенных примеров является List
, возвращаемый Arrays.asList()
: он документирован не для поддержки любых структурных изменений (например, удаление или добавление элементов) (внимание мое):
Возвращает список фиксированного размера, поддерживаемый указанным массивом.
Даже если это не конкретный List
, который вы пытаетесь изменить, ответ по-прежнему применяется к другим реализациям List
, которые либо неизменяемы, либо разрешают только некоторые выбранные изменения.
Об этом вы можете узнать, прочитав документацию UnsupportedOperationException
и List.add()
, который документирует это как "(необязательная операция)". Точный смысл этой фразы объясняется в верхней части документации List
.
В качестве обходного пути вы можете создать копию списка для известной модификации, например ArrayList
:
seeAlso = new ArrayList<>(seeAlso);
Ответ 2
Вы должны инициализировать свой список seeAlso:
List<String> seeAlso = new Vector<String>();
или
List<String> seeAlso = new ArrayList<String>();
Ответ 3
Многие из реализации List поддерживают ограниченную поддержку для добавления/удаления, и одним из них является Arrays.asList(membersArray). Вам необходимо вставить запись в java.util.ArrayList или использовать приведенный ниже подход для преобразования в ArrayList.
С минимальными изменениями в вашем коде, вы можете сделать ниже, чтобы преобразовать список в ArrayList. Первое решение имеет минимальные изменения в вашем решении, но второе, я думаю, более оптимизировано.
String[] membersArray = request.getParameterValues('members');
ArrayList<String> membersList = new ArrayList<>(Arrays.asList(membersArray));
ИЛИ ЖЕ
String[] membersArray = request.getParameterValues('members');
ArrayList<String> membersList = Stream.of(membersArray).collect(Collectors.toCollection(ArrayList::new));
Ответ 4
Сформируйте концепцию наследования. Если какой-либо перикулярный метод недоступен в текущем классе, он будет искать этот метод в суперклассах. Если доступно, оно выполняется.
Он выполняет метод add()
класса AbstractList<E>
который генерирует UnsupportedOperationException
.
Когда вы конвертируете из массива в коллекционный объект. то есть, на основе массива к API на основе коллекции, то он предоставит вам объект коллекции фиксированного размера, потому что поведение массива имеет фиксированный размер.
java.util.Arrays.asList(T... a)
Образцы соусов для конформации.
public class Arrays {
public static <T> List<T> asList(T... a) {
return new java.util.Arrays.ArrayList.ArrayList<>(a); // Arrays Inner Class ArrayList
}
//...
private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable {
//...
}
}
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
public E remove(int index) {
throw new UnsupportedOperationException();
}
public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
//...
}
public ListIterator<E> listIterator() {
return listIterator(0);
}
private class ListItr extends Itr implements ListIterator<E> {
//...
}
}
Из вышеприведенного источника вы можете заметить, что класс java.util.Arrays.ArrayList
не @Override add(index, element), set(index, element), remove(index)
. Итак, из наследования он выполняет супер-функцию класса AbstractList<E>
add()
которая генерирует UnsupportedOperationException
.
Поскольку AbstractList<E>
является абстрактным классом, он обеспечивает реализацию для iterator() and listIterator()
. Таким образом, мы можем перебрать объект списка.
List<String> list_of_Arrays = Arrays.asList(new String[] { "a", "b" ,"c"});
try {
list_of_Arrays.add("Yashwanth.M");
} catch(java.lang.UnsupportedOperationException e) {
System.out.println("List Interface executes AbstractList add() fucntion which throws UnsupportedOperationException.");
}
System.out.println("Arrays → List : " + list_of_Arrays);
Iterator<String> iterator = list_of_Arrays.iterator();
while (iterator.hasNext()) System.out.println("Iteration : " + iterator.next() );
ListIterator<String> listIterator = list_of_Arrays.listIterator();
while (listIterator.hasNext()) System.out.println("Forward iteration : " + listIterator.next() );
while(listIterator.hasPrevious()) System.out.println("Backward iteration : " + listIterator.previous());
Вы даже можете создать массив массивов фиксированного размера. Коллекции class Collections.unmodifiableList(list);
Источник выборки:
public class Collections {
public static <T> List<T> unmodifiableList(List<? extends T> list) {
return (list instanceof RandomAccess ?
new UnmodifiableRandomAccessList<>(list) :
new UnmodifiableList<>(list));
}
}
Collection
иногда называемая контейнером, - это просто объект, который группирует несколько элементов в одну единицу. Коллекции используются для хранения, извлечения, обработки и передачи сводных данных.
@смотрите также
Ответ 5
вместо использования add() мы можем использовать addall() seeAlso.addall(groupDn);
add добавляет один элемент, а addAll добавляет каждый элемент из коллекции по одному. В конце оба метода возвращают true, если коллекция была изменена. В случае ArrayList это тривиально, потому что коллекция всегда изменяется, но другие коллекции, такие как Set, могут возвращать false, если добавляемые элементы уже есть.
Ответ 6
List membersList = Arrays.asList(membersArray);
возвращает неизменный список, что вам нужно сделать, это
новый ArrayList<> (Arrays.asList(membersArray)); сделать его изменчивым
Ответ 7
Вы не можете изменить результат из запроса LDAP. Ваша проблема в этой строке:
seeAlso.add(groupDn);
Список seeAlso не может быть изменен.