Java List.add()UnsupportedOperationException

ct2axkht  于 2023-04-28  发布在  Java
关注(0)|答案(9)|浏览(225)

我尝试向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)
px9o7tmv

px9o7tmv1#

并非每个List实现都支持add()方法。
一个常见的例子是Arrays.asList()返回的List:它被记录为以支持任何结构修饰(即,e.删除或添加元素)(强调我的):
返回指定数组支持的固定大小列表。
即使这不是您试图修改的特定List,答案仍然适用于其他List实现,这些实现要么是不可变的,要么只允许一些选定的更改。
您可以通过阅读UnsupportedOperationExceptionList.add()的文档来了解这一点,这些文档将其记录为“(可选操作)”。这个短语的确切含义在List文档的顶部解释。
作为一种解决方法,您可以创建列表的副本到已知可修改的实现,如ArrayList

seeAlso = new ArrayList<>(seeAlso);
gpnt7bae

gpnt7bae2#

许多List实现支持对添加/删除和阵列的有限支持。asList(membersArray)就是其中之一。你需要在java中插入记录。或者使用下面的方法转换成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));
fruv7luv

fruv7luv3#

从继承的概念来看,如果某个特定的方法在当前类中不可用,它将在超类中搜索该方法。如果可用,则执行。
执行**AbstractList<E>classadd()**方法抛出UnsupportedOperationException
当您从数组转换为集合对象时。也就是说,从基于数组到基于集合的API,那么它将为您提供固定大小的集合对象,因为Array的行为是固定大小的。
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对象。

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);创建固定大小的数组
样品来源:

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

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

tcomlyy6

tcomlyy64#

如果您尝试addCollections.singletonList(T o)返回的List<T>,也会得到此异常:
返回只包含指定对象的不可变列表。返回的列表是可序列化的。
JVM未为Collections.singletonList实现add()

unhi4e5o

unhi4e5o5#

List membersList = Arrays.sList();
返回不可变列表,你需要做的是
new ArrayList〈〉(Arrays.getString(String);使其可变

ff29svar

ff29svar6#

您必须初始化您的列表另请参阅:

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

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

ujv3wf0j7#

出现UnsupportedOperationException的原因是数组。asList()方法返回由原始数组支持的固定大小的列表。这意味着您不能通过添加或删除元素来修改列表的大小,尝试这样做将导致UnsupportedOperationException。

z9gpfhce

z9gpfhce8#

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

seeAlso.add(groupDn);

“请参阅”列表不可修改。

q0qdq0h2

q0qdq0h29#

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

{ seeAlso.addall(groupDn); }

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

相关问题