[英]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)
并非每个List
实现都支持add()
方法。
一个常见的例子是Arrays.asList()
返回的List
:它被记录为不支持任何结构修改(即删除或添加元素)(强调我的):
返回由指定数组支持的固定大小列表。
即使这不是您要修改的特定List
,答案仍然适用于其他不可变或仅允许某些选定更改的List
实现。
您可以通过阅读UnsupportedOperationException
和List.add()
的文档来了解这一点,其中将其记录为“(可选操作)”。 该短语的确切含义在List
文档的顶部进行了解释。
作为一种解决方法,您可以将列表的副本创建为已知的可修改实现,例如ArrayList
:
seeAlso = new ArrayList<>(seeAlso);
许多 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 那么它将为您提供固定大小的集合对象,因为 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> {
//...
}
}
从上面的 Source 中,您可能会观察到java.util.Arrays.ArrayList
类没有@Override add(index, element), set(index, element), remove(index)
。 因此,从继承它执行 super AbstractList<E>
class 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());
你甚至可以创建固定大小的数组形式集合类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
——有时也称为容器——只是一个将多个元素组合成一个单元的对象。 集合用于存储、检索、操作和交流聚合数据。
@也可以看看
如果您尝试add
到Collections.singletonList(T o)
返回的List<T>
您也会收到此异常:
返回仅包含指定对象的不可变列表。 返回的列表是可序列化的。
JVM 没有为Collections.singletonList
实现add()
您必须初始化您的 List seeAlso :
List<String> seeAlso = new Vector<String>();
或者
List<String> seeAlso = new ArrayList<String>();
List membersList = Arrays.asList(membersArray);
返回不可变列表,你需要做的是
新 ArrayList<>(Arrays.asList(membersArray)); 使其可变
您不能修改 LDAP 查询的结果。 你的问题在这一行:
seeAlso.add(groupDn);
seeAlso 列表是不可修改的。
我们可以使用 addall() 代替 add()
{ seeAlso.addall(groupDn); }
add 添加单个项目,而 addAll 一个一个地添加集合中的每个项目。 最后,如果集合已被修改,两种方法都返回 true。 在 ArrayList 的情况下,这是微不足道的,因为集合总是被修改,但是如果要添加的项目已经存在,则其他集合(例如 Set)可能会返回 false。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.