Java List.add () UnsupportedOperationException


225

मैं एक 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)

जवाबों:


457

प्रत्येक Listकार्यान्वयन add()विधि का समर्थन नहीं करता है ।

एक सामान्य उदाहरण Listद्वारा दिया गया है Arrays.asList(): यह किसी भी संरचनात्मक संशोधन (यानी तत्वों को हटाने या जोड़ने) (जोर मेरा) का समर्थन नहीं करने के लिए प्रलेखित है :

निर्दिष्ट सरणी द्वारा समर्थित एक निश्चित आकार की सूची देता है ।

यहां तक ​​कि अगर वह विशिष्ट नहीं है जिसे Listआप संशोधित करने का प्रयास कर रहे हैं, तो उत्तर अभी भी अन्य Listकार्यान्वयनों पर लागू होता है जो या तो अपरिवर्तनीय हैं या केवल कुछ चयनित परिवर्तनों की अनुमति देते हैं।

आप इसके बारे में यह पता लगा सकते हैं कि कौन से दस्तावेज हैं, UnsupportedOperationExceptionऔर List.add()कौन से दस्तावेज "(वैकल्पिक संचालन)" हैं। इस वाक्यांश का सटीक अर्थ Listप्रलेखन के शीर्ष पर समझाया गया है।

वर्कअराउंड के रूप में आप सूची की एक प्रतिलिपि एक ज्ञात-परिवर्तनीय कार्यान्वयन के लिए बना सकते हैं जैसे ArrayList:

seeAlso = new ArrayList<>(seeAlso);

1
इसलिए मुझे यह जाँचने के लिए सूची उदाहरण का उपयोग करना होगा कि क्या इसमें मेरा तत्व और सरणी उदाहरण है जब मुझे कोई तत्व जोड़ना है? वो लिखा हुआ है?
फजिर

90
@Florito: यह हालांकि काम करेगा: List<String> listMembres = new ArrayList<String>(Arrays.asList(tabMembres));:)
mre

या हो सकता है कि मुझे अपनी सूची ऑब्जेक्ट को ArrayList या किसी अन्य को डालना होगा?
फजीर

2
नहीं वास्तव में नहीं। यदि आप किसी Listकार्यान्वयन में एक तत्व जोड़ना चाहते हैं जो इसके अलावा की अनुमति नहीं देता है, तो आपको इसे उस Listकार्यान्वयन के लिए कॉपी करना होगा जो ( ArrayListएक सामान्य उम्मीदवार है) और उसी में जोड़ें।
जोकिम सॉर

8

सूची कार्यान्वयन में से कई को जोड़ने / हटाने के लिए सीमित समर्थन का समर्थन है, और 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));

4

इनहेरिटेंस कॉन्सेप्ट को फॉर्म करें, यदि वर्तमान वर्ग में कुछ पर्टिकुलर विधि उपलब्ध नहीं है तो यह सुपर क्लास में उस विधि की खोज करेगा। यदि उपलब्ध हो तो क्रियान्वित होता है।

यह AbstractList<E>कक्षा add()पद्धति को कार्यान्वित करता है जो फेंकता है UnsupportedOperationException


जब आप एक सरणी से एक संग्रह Obejct में परिवर्तित कर रहे हैं। यानी, संग्रह-आधारित एपीआई के लिए सरणी-आधारित तो यह आपको निश्चित-आकार संग्रह वस्तु प्रदान करने वाला है, क्योंकि एरे का व्यवहार निश्चित आकार का है।

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.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- कभी-कभी कंटेनर कहा जाता है - बस एक वस्तु है जो कई तत्वों को एक इकाई में समूहित करता है। एकत्रित डेटा को संग्रहीत करने, पुनः प्राप्त करने, हेरफेर करने और संचार करने के लिए संग्रह का उपयोग किया जाता है।

@यह सभी देखें


3

आपको अपनी सूची देखना आरंभ करना होगा।

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

या

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

2
एक अनधिकृत चर UnsupportedOperationExceptionमें कारण नहीं होगा add()। आपको इसके बजाय एक NPE मिलेगा।
स्टीफन सी

0

सूची के सदस्य = Arrays.asList (membersArray);

अपरिवर्तनीय सूची देता है, जो आपको करने की आवश्यकता है

नया ArrayList <> (Arrays.asList (membersArray)); इसे बदलने योग्य बनाने के लिए


यह एक अपरिवर्तनीय सूची नहीं है। म्यूटेशन ऑपरेशन जो सूची की लंबाई को नहीं बदलते हैं वे समर्थित हैं / काम करेंगे। महत्वपूर्ण बात यह है कि सूची की लंबाई नहीं बदल सकती क्योंकि सूची सरणी द्वारा समर्थित है ... जिसकी लंबाई परिवर्तित नहीं हो सकती।
स्टीफन सी

-1

Add () का उपयोग करने के बजाय हम addall () का उपयोग कर सकते हैं

{ seeAlso.addall(groupDn); }

add एक आइटम जोड़ता है, जबकि addAll प्रत्येक आइटम को एक-एक करके संग्रह से जोड़ता है। अंत में, यदि संग्रह को संशोधित किया गया है, तो दोनों विधियाँ सही होती हैं। ArrayList के मामले में यह तुच्छ है, क्योंकि संग्रह को हमेशा संशोधित किया जाता है, लेकिन अन्य संग्रह, जैसे कि सेट, गलत हो सकता है यदि जोड़े गए आइटम पहले से ही हैं।


-3

आप LDAP क्वेरी से परिणाम को संशोधित नहीं कर सकते। आपकी समस्या इस पंक्ति में है:

seeAlso.add(groupDn);

SeeAlso सूची unmodifiable है।


1
समस्या इसके कारण नहीं है, लेकिन जैसा कि जोआचिम ने बताया है कि यह सूची के कार्यान्वयन के साथ करना है जो कि ऐड () का समर्थन नहीं कर सकता है।
Liv
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.