[java] Java List.add () UnsupportedOperationException

List<String>인스턴스 에 객체를 추가하려고 시도 하지만가 발생합니다 UnsupportedOperationException. 아무도 이유를 알고 있습니까?

내 자바 코드 :

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 (알 수없는 소스)
    java.util.AbstractList.add (알 수없는 소스)
    javax.servlet.http.HttpServlet.service (HttpServlet.java:641)
    javax.servlet.http.HttpServlet.service (HttpServlet.java:722)



답변

모든 List구현이 add()메소드를 지원하는 것은 아닙니다 .

하나의 일반적인 예는 다음에 List의해 반환됩니다 Arrays.asList(). 구조적 수정 (예 : 요소 제거 또는 추가)을 지원 하지 않는 것으로 문서화 되어 있습니다 (강조 광산).

지정된 배열이 지원 하는 고정 크기 목록을 반환합니다 .

그것이 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));


답변

상속 개념을 형성하십시오. 현재 클래스에서 일부 perticular 메소드를 사용할 수 없으면 수퍼 클래스에서 해당 메소드를 검색합니다. 사용 가능한 경우 실행됩니다.

던지는 AbstractList<E>클래스 add()메소드를 실행 UnsupportedOperationException합니다.


Array에서 Collection Obejct로 변환 할 때 즉, 배열 기반의 컬렉션 기반 API에서 배열의 동작은 고정 크기이므로 고정 크기의 컬렉션 객체를 제공합니다.

java.util.Arrays.asList (T … a)

형태를위한 Souce 샘플.

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컨테이너라고도하는 는 단순히 여러 요소를 단일 단위로 그룹화하는 객체입니다. 컬렉션은 집계 데이터를 저장, 검색, 조작 및 통신하는 데 사용됩니다.

@또한보십시오


답변

List를 초기화해야합니다.

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

또는

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


답변

List membersList = Arrays.asList (membersArray);

불변 목록을 반환합니다.

새로운 ArrayList <> (Arrays.asList (membersArray)); 변경 가능하도록


답변

add ()를 사용하는 대신 addall ()을 사용할 수 있습니다

{ seeAlso.addall(groupDn); }

add는 단일 항목을 추가하는 반면 addAll은 컬렉션의 각 항목을 하나씩 추가합니다. 결국 컬렉션이 수정 된 경우 두 방법 모두 true를 반환합니다. ArrayList의 경우 컬렉션은 항상 수정되기 때문에 간단하지만 추가되는 항목이 이미 있으면 Set과 같은 다른 컬렉션은 false를 반환 할 수 있습니다.


답변

LDAP 쿼리에서 결과를 수정할 수 없습니다. 문제는 다음 줄에 있습니다.

seeAlso.add(groupDn);

seeAlso 목록도 수정할 수 없습니다.