Danh sách Java.add () UnsupportedOperationException


225

Tôi cố gắng thêm các đối tượng vào một List<String>thể hiện nhưng nó ném một UnsupportedOperationException. Có ai biết tại sao không?

Mã Java của tôi:

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);
    }
}

Thông báo lỗi:

java.lang.UnsupportedOperationException
    java.util.Ab tríchList.add (Nguồn không xác định)
    java.util.Ab tríchList.add (Nguồn không xác định)
    javax.servlet.http.HttpServlet.service (httpServlet.java:641)
    javax.servlet.http.HttpServlet.service (httpServlet.java:722)

Câu trả lời:


457

Không phải mọi Listthực hiện đều hỗ trợ add()phương pháp.

Một ví dụ phổ biến là Listtrả về bởi Arrays.asList(): nó được ghi nhận là không hỗ trợ bất kỳ sửa đổi cấu trúc nào (tức là loại bỏ hoặc thêm các phần tử) (nhấn mạnh của tôi):

Trả về một danh sách kích thước cố định được hỗ trợ bởi mảng đã chỉ định.

Ngay cả khi đó không phải là cụ thể Listmà bạn đang cố gắng sửa đổi, câu trả lời vẫn được áp dụng cho các Listtriển khai khác không thay đổi hoặc chỉ cho phép một số thay đổi được chọn.

Bạn có thể tìm hiểu về điều này bằng cách đọc tài liệu của UnsupportedOperationExceptionList.add(), tài liệu này là "(hoạt động tùy chọn)". Ý nghĩa chính xác của cụm từ này được giải thích ở đầu Listtài liệu.

Như một giải pháp thay thế, bạn có thể tạo một bản sao của danh sách để triển khai có thể sửa đổi như ArrayList:

seeAlso = new ArrayList<>(seeAlso);

1
vì vậy tôi phải sử dụng thể hiện danh sách để kiểm tra xem nó có chứa phần tử của tôi và thể hiện mảng khi tôi phải thêm một phần tử không? đó là viết?
FAjir

90
@Florito: Điều này sẽ hoạt động mặc dù: List<String> listMembres = new ArrayList<String>(Arrays.asList(tabMembres));:)
mre

hoặc có lẽ tôi phải truyền đối tượng List của mình sang ArrayList hoặc khác?
FAjir

2
Không thật sự lắm. Nếu bạn muốn thêm một yếu tố vào một Listtriển khai không cho phép bổ sung, thì bạn sẽ phải sao chép nó Listvào một triển khai thực hiện ( ArrayListlà một ứng cử viên phổ biến) và thêm vào đó.
Joachim Sauer

8

Nhiều hỗ trợ triển khai Danh sách hỗ trợ giới hạn để thêm / xóa và Arrays.asList (thành viênArray) là một trong số đó. Bạn cần chèn bản ghi trong java.util.ArrayList hoặc sử dụng cách tiếp cận dưới đây để chuyển đổi thành ArrayList.

Với sự thay đổi tối thiểu trong mã của bạn, bạn có thể thực hiện bên dưới để chuyển đổi danh sách sang ArrayList. Giải pháp đầu tiên là có một sự thay đổi tối thiểu trong giải pháp của bạn, nhưng giải pháp thứ hai được tối ưu hóa hơn, tôi đoán vậy.

    String[] membersArray = request.getParameterValues('members');
    ArrayList<String> membersList = new ArrayList<>(Arrays.asList(membersArray));

HOẶC LÀ

    String[] membersArray = request.getParameterValues('members');
    ArrayList<String> membersList = Stream.of(membersArray).collect(Collectors.toCollection(ArrayList::new));

4

Hình thành khái niệm Kế thừa, Nếu một số phương thức vuông góc không có sẵn trong lớp hiện tại, nó sẽ tìm kiếm phương thức đó trong các siêu lớp. Nếu có sẵn nó thực thi.

Nó thực hiện phương thức AbstractList<E>lớp add()mà ném UnsupportedOperationException.


Khi bạn đang chuyển đổi từ Mảng sang Bộ sưu tập Obejct. tức là, API dựa trên mảng để dựa trên bộ sưu tập, sau đó nó sẽ cung cấp cho bạn đối tượng bộ sưu tập có kích thước cố định, vì hành vi của Array có kích thước Cố định.

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

Mẫu Souce cho hình dạng.

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> {
        //...
    }
}

Hình thành Nguồn trên bạn có thể quan sát thấy java.util.Arrays.ArrayListlớp đó không @Override add(index, element), set(index, element), remove(index). Vì vậy, từ thừa kế, nó thực hiện chức năng siêu AbstractList<E>hạng add()mà ném UnsupportedOperationException.

Như AbstractList<E>là một lớp trừu tượng, nó cung cấp việc thực hiện iterator() and listIterator(). Vì vậy, chúng ta có thể lặp qua đối tượng danh sách.

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());

Bạn thậm chí có thể tạo lớp Bộ sưu tập dạng mảng Kích thước cố định Collections.unmodifiableList(list);

Nguồn mẫu:

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

Một Collection- đôi khi được gọi là một thùng chứa - chỉ đơn giản là một đối tượng nhóm nhiều phần tử thành một đơn vị. Bộ sưu tập được sử dụng để lưu trữ, truy xuất, thao tác và giao tiếp dữ liệu tổng hợp.

@Xem thêm


3

Bạn phải khởi tạo Danh sách của mình xem Ngoài ra:

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

hoặc là

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

2
Một biến chưa được khởi tạo sẽ không gây ra UnsupportedOperationExceptiontrong add(). Bạn sẽ nhận được một NPE thay thế.
Stephen C

0

Liệt kê thành viênList = Arrays.asList (thành viênArray);

trả về danh sách bất biến, điều bạn cần làm là

ArrayList mới <> (Arrays.asList (thành viênArray)); để làm cho nó có thể thay đổi


Nó không phải là một danh sách bất di bất dịch. Các hoạt động đột biến không thay đổi độ dài danh sách được hỗ trợ / sẽ hoạt động. Điều quan trọng là độ dài của danh sách không thể thay đổi vì danh sách được hỗ trợ bởi một mảng ... có độ dài không thể thay đổi.
Stephen C

-1

thay vì sử dụng add () chúng ta có thể sử dụng addall ()

{ seeAlso.addall(groupDn); }

add thêm một mục duy nhất, trong khi addAll thêm từng mục từ bộ sưu tập từng cái một. Cuối cùng, cả hai phương thức đều trả về true nếu bộ sưu tập đã được sửa đổi. Trong trường hợp ArrayList, điều này là không quan trọng, bởi vì bộ sưu tập luôn được sửa đổi, nhưng các bộ sưu tập khác, chẳng hạn như Set, có thể trả về false nếu các mục được thêm vào đã có sẵn.


-3

Bạn không thể sửa đổi kết quả từ truy vấn LDAP. Vấn đề của bạn là trong dòng này:

seeAlso.add(groupDn);

Danh sách seeAlso là không thể thay đổi.


1
vấn đề không phải là do điều đó mà như Joachim đã chỉ ra ở trên, đó là do việc triển khai Danh sách có thể không hỗ trợ add ().
Liv
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.