web-dev-qa-db-ja.com

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)
175
FAjir

すべての List 実装がadd()メソッドをサポートしているわけではありません。

一般的な例の1つは、 Arrays.asList() によって返されるListです。構造変更(つまり、要素の削除または追加)をサポートするために文書化されていますnot )(強調鉱山):

指定された配列に連動するfixed-sizeリストを返します。

修正しようとしている特定のListでなくても、答えは不変であるか、選択した変更のみを許可する他のList実装に適用されます。

これについては、 UnsupportedOperationException および List.add() のドキュメントを参照してください。このドキュメントでは、「(オプションの操作)」と記載されています。この句の正確な意味は、Listドキュメントの上部で説明されています。

回避策として、リストのコピーをArrayListのような既知の変更可能な実装に作成できます。

seeAlso = new ArrayList<>(seeAlso);
362
Joachim Sauer

リストを初期化する必要がありますseeAlso:

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

または

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

継承の概念を形成します。特定のメソッドが現在のクラスで利用できない場合、スーパークラスでそのメソッドを検索します。利用可能な場合は実行されます。

AbstractList<E>classadd()スローするメソッド UnsupportedOperationException


配列からコレクションオブジェクトに変換するとき。つまり、配列ベースのコレクションからコレクションベースの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)ではないことがわかります。したがって、継承から、UnsupportedOperationExceptionをスローするスーパーAbstractList<E>クラスadd()関数を実行します。

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 —コンテナとも呼ばれる—は、複数の要素を単一のユニットにグループ化するオブジェクトです。コレクションは、集計データの保存、取得、操作、および通信に使用されます。

@seeも

2
Yash

リストの実装の多くは、追加/削除のサポートが制限されており、Arrays.asList(membersArray)もその1つです。 Java.util.ArrayListにレコードを挿入するか、以下のアプローチを使用してArrayListに変換する必要があります。

コードに最小限の変更を加えるだけで、以下を実行してリストをArrayListに変換できます。最初の解決策はソリューションに最小限の変更を加えることですが、2番目の解決策はより最適化されていると思います。

    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));
2
krmanish007

リストmembersList = Arrays.asList(membersArray);

不変リストを返します、あなたがする必要があるのは

new ArrayList <>(Arrays.asList(membersArray));可変にする

0
Ziv.Ti

add()を使用する代わりに、addall()を使用できます

{ seeAlso.addall(groupDn); }

addは単一のアイテムを追加し、addAllはコレクションから各アイテムを1つずつ追加します。最後に、コレクションが変更された場合、両方のメソッドはtrueを返します。 ArrayListの場合、コレクションは常に変更されますが、追加されるアイテムが既に存在する場合、Setなどの他のコレクションがfalseを返すため、これは簡単です。

0
Allen