Java List.add() UnsupportedOperationException

我尝试向List<String>实例添加对象,但它抛出UnsupportedOperationException。 有人知道为什么吗?< / p >

我的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)
200735 次浏览

并不是每个List实现都支持add()方法。

一个常见的例子是Arrays.asList()返回的List:它被记录为以支持任何结构修改(即删除或添加元素)(强调我的):

返回指定数组支持的固定大小列表。

即使这不是你试图修改的特定List,答案仍然适用于其他List实现,它们要么是不可变的,要么只允许一些选定的更改。

你可以通过阅读UnsupportedOperationExceptionList.add()的文档来了解这一点,它们将此记录为“(可选操作)”。这个短语的确切含义在List文档的顶部进行了解释。

作为一种变通方法,你可以创建一个列表的副本到一个已知的可修改的实现,如ArrayList:

seeAlso = new ArrayList<>(seeAlso);

不能修改LDAP查询的结果。你的问题在这一行:

seeAlso.add(groupDn);

seeAlso列表是不可修改的。

你必须初始化你的列表

List<String> seeAlso = new Vector<String>();

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

List membersList = Arrays.asList(membersArray);

返回不可变列表,你需要做的是

新的ArrayList< > (arrays . aslist (membersArray));使它可变

许多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));

形成继承概念,如果某个特定的方法在当前类中不可用,它将在超类中搜索该方法。如果可用,则执行。

它执行AbstractList<E>add()方法,该方法抛出UnsupportedOperationException


当您将数组转换为集合对象时。例如,基于数组的API到基于集合的API,那么它将为你提供固定大小的集合对象,因为数组的行为是固定大小的。

java.util.Arrays。asList (T…一)

构象的源样本。

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对象。

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());

你甚至可以创建固定大小的数组集合类Collections.unmodifiableList(list);

< p >样本来源:

public class Collections {
public static <T> List<T> unmodifiableList(List<? extends T> list) {
return (list instanceof RandomAccess ?
new UnmodifiableRandomAccessList<>(list) :
new UnmodifiableList<>(list));
}
}

Collection -有时称为容器-只是一个对象,它将多个元素组合成一个单元。集合用于存储、检索、操作和通信聚合数据。

@see也

我们可以使用addall()代替add()

{ seeAlso.addall(groupDn); }

add添加单个项,而addAll则逐个添加集合中的每个项。最后,如果集合已被修改,两个方法都返回true。对于ArrayList来说,这是微不足道的,因为集合总是被修改,但其他集合,如Set,如果添加的项已经在那里,则可能返回false。

如果你试图将add转换为Collections.singletonList(T o)返回的List<T>,你也会得到这个异常:

返回只包含指定对象的不可变的列表。返回的列表是可序列化的。

JVM没有为Collections.singletonList实现add()