我尝试将对象添加到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)
答案 0 :(得分:358)
并非每个List
实现都支持add()
方法。
一个常见示例是Arrays.asList()
返回的List
:记录不以支持任何结构修改(即删除或添加元素)(强调我的):< / p>
返回由指定数组支持的固定大小列表。
即使这不是您尝试修改的特定List
,答案仍然适用于其他List
实现,这些实现是不可变的或仅允许某些选定的更改。
您可以通过阅读UnsupportedOperationException
和List.add()
的文档来了解相关信息,该文档将此文档记录为“(可选操作)”。 List
文档的顶部解释了这个短语的确切含义。
作为一种解决方法,您可以将列表副本创建为ArrayList
等已知可修改的实现:
seeAlso = new ArrayList<>(seeAlso);
答案 1 :(得分:3)
您必须初始化List seeAlso:
List<String> seeAlso = new Vector<String>();
或
List<String> seeAlso = new ArrayList<String>();
答案 2 :(得分:1)
许多List实现支持有限的添加/删除支持,而Arrays.asList(membersArray)就是其中之一。您需要将记录插入到java.util.ArrayList中,或使用以下方法转换为ArrayList。
在代码中进行最小的更改,您可以执行以下操作以将列表转换为ArrayList。我猜第一种解决方案的更改最少,但是第二种解决方案更优化。
String[] membersArray = request.getParameterValues('members');
ArrayList<String> membersList = new ArrayList<>(Arrays.asList(membersArray));
OR
String[] membersArray = request.getParameterValues('members');
ArrayList<String> membersList = Stream.of(membersArray).collect(Collectors.toCollection(ArrayList::new));
答案 3 :(得分:1)
形成继承概念,如果当前类中没有某些垂直方法,它将在超类中搜索该方法。如果可用,它将执行。
它执行
AbstractList<E>
类add()
方法,该方法抛出UnsupportedOperationException
。
从数组转换为集合对象时。即基于数组的API到基于集合的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());
您甚至可以创建固定大小的数组表单Collections类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
(有时也称为容器)只是将多个元素组合为一个单元的对象。集合用于存储,检索,操作和传达聚合数据。
@另请参见
答案 4 :(得分:0)
我们可以使用addall()而不是使用add()
{ seeAlso.addall(groupDn); }
add仅添加一个项目,而addAll则一个接一个地添加集合中的每个项目。最后,如果对集合进行了修改,则这两个方法均返回true。对于ArrayList来说,这是微不足道的,因为该集合始终会被修改,但是如果要添加的项已经存在,则其他集合(例如Set)可能会返回false。
答案 5 :(得分:0)
如果您尝试对 Collections.singletonList(T o)
返回的 add
进行 List<T>
,您也会收到此异常:
返回一个仅包含指定对象的不可变列表。返回的列表是可序列化的。
JVM 没有为 add()
实现 Collections.singletonList
答案 6 :(得分:-1)
列表memberList = Arrays.asList(membersArray);
返回不可变列表,您需要做的是
新ArrayList <>(Arrays.asList(membersArray));使其可变
答案 7 :(得分:-3)
您无法修改LDAP查询的结果。你的问题就在这一行:
seeAlso.add(groupDn);
seeAlso列表是不可修改的。