Arrays.asList (सरणी) और नए ArrayList <Integer> (Arrays.asList (सरणी)) के बीच अंतर


119

दोनों के बीच क्या अंतर है

1.List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));  //copy
2.List<Integer> list2 = Arrays.asList(ia);

iaपूर्णांकों की सरणी कहां है।

मुझे पता चला कि कुछ संचालन की अनुमति नहीं है list2। ऐसा क्यों है? इसे मेमोरी (संदर्भ / कॉपी) में कैसे संग्रहीत किया जाता है?

जब मैं सूचियों में फेरबदल करता हूं, list1तो मूल सरणी को प्रभावित नहीं list2करता है। लेकिन फिर भी list2कुछ गड़बड़ है।

कैसे ArrayListसूची के लिए upcasted किया जा रहा है नया बनाने से अलग हैArrayList

list1 differs from (1)
ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));

2
मेरा सुझाव है कि आप Google अमरूद के विकल्प को देखें। Lists.newArrayList(ia)पहले विकल्प के रूप में, एक स्वतंत्र प्रतिलिपि बनाता है। यह बस देखने के लिए अधिक सामान्य और बेहतर है।
क्यूबेन

जवाबों:


228
  1. सबसे पहले, आइए देखें कि यह क्या करता है:

    Arrays.asList(ia)

    यह एक सरणी लेता है iaऔर एक आवरण बनाता है जो लागू करता है List<Integer>, जो मूल सरणी को सूची के रूप में उपलब्ध करता है। कुछ भी कॉपी नहीं किया जाता है और सभी, केवल एक आवरण वस्तु बनाई जाती है। सूची आवरण पर परिचालनों को मूल सरणी में प्रचारित किया जाता है। इसका मतलब यह है कि यदि आप सूची आवरण को फेरते हैं, तो मूल सरणी को भी फेरबदल किया जाता है, यदि आप किसी तत्व को अधिलेखित करते हैं, तो यह मूल सरणी में ओवरराइट हो जाता है, आदि, निश्चित रूप Listसे आवरण पर कुछ संचालन की अनुमति नहीं है, जैसे जोड़ना या सूची से तत्वों को हटाकर, आप केवल तत्वों को पढ़ या अधिलेखित कर सकते हैं।

    ध्यान दें कि सूची आवरण विस्तृत नहीं है ArrayList- यह एक अलग प्रकार की वस्तु है। ArrayLists उनकी अपनी आंतरिक सारणी होती है, जिसमें वे अपने तत्वों को संग्रहीत करते हैं, और आंतरिक सरणियों आदि का आकार बदलने में सक्षम होते हैं। आवरण के पास अपना आंतरिक सरणी नहीं होता है, यह केवल इसके लिए दिए गए सरणी में संचालन का प्रचार करता है।

  2. दूसरी ओर, यदि आप बाद में एक नया सरणी बनाते हैं

    new ArrayList<Integer>(Arrays.asList(ia))

    तब आप नया बनाते हैं ArrayList, जो मूल एक की पूर्ण, स्वतंत्र प्रति है। यद्यपि यहां आप रैपर का उपयोग करते हुए बनाते हैं Arrays.asList, इसका उपयोग केवल नए के निर्माण के दौरान किया जाता है ArrayListऔर बाद में कचरा एकत्र किया जाता है। इस नई की संरचना ArrayListमूल सरणी से पूरी तरह से स्वतंत्र है। इसमें समान तत्व शामिल हैं (दोनों मूल सरणी और यह नया ArrayListसंदर्भ मेमोरी में समान पूर्णांक), लेकिन यह एक नया, आंतरिक सरणी बनाता है, जो संदर्भ रखता है। इसलिए जब आप इसे फेरबदल करते हैं, तो तत्वों को जोड़ते हैं, हटाते हैं, मूल सरणी अपरिवर्तित रहते हैं।


9
@ दिनेशकुमार एक आवरण एक डिज़ाइन पैटर्न है जो एक वर्ग के लिए एक इंटरफ़ेस को दूसरे इंटरफ़ेस में अनुवाद करता है। देखें आवरण पैटर्न लेख। | आपको कहां तक ​​की आवश्यकता है? मैं List<Integer>आपके चर प्रकार (या विधि तर्क आदि) के लिए उपयोग करने का सुझाव दूंगा। यह आपके कोड को अधिक सामान्य बनाता है और आप आसानी से Listआवश्यकतानुसार किसी अन्य कार्यान्वयन पर स्विच कर सकते हैं , बिना बहुत सारे कोड को फिर से लिखना।
पेट्र पुडलक

यह एक अच्छी व्याख्या है। इस प्रश्न का विस्तार करते हुए, Arrays.asList () विधि भी varargs लेती है। यदि मैं विशिष्ट मान पास करता हूं, तो मैं कहता हूं: Arrays.asList (1,3,5) दो बार, क्या यह समान सूची लौटाएगा?
sbsatter

27

खैर यह इसलिए है क्योंकि ArrayListपरिणाम Arrays.asList()प्रकार का नहीं है java.util.ArrayListArrays.asList()एक ArrayListप्रकार बनाता है java.util.Arrays$ArrayListजो विस्तारित नहीं होता है java.util.ArrayListबल्कि केवल विस्तारित होता हैjava.util.AbstractList


9
List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));  //copy

इस मामले में, list1प्रकार का है ArrayList

List<Integer> list2 = Arrays.asList(ia);

यहां, सूची को एक Listदृश्य के रूप में लौटाया गया है , जिसका अर्थ है कि इसमें केवल उस इंटरफ़ेस से जुड़ी विधियां हैं। इसलिए कुछ तरीकों पर अनुमति नहीं है list2

ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));

यहाँ, आप एक नया बना रहे हैं ArrayList। आप बस इसे कंस्ट्रक्टर में मान दे रहे हैं। यह कास्टिंग का उदाहरण नहीं है। कास्टिंग में, यह इस तरह दिख सकता है:

ArrayList list1 = (ArrayList)Arrays.asList(ia);

4

मैं यहाँ बहुत देर हो चुकी हूँ, वैसे भी किसी को भी डॉक संदर्भों के साथ एक स्पष्टीकरण लगा जो किसी के लिए उत्तर की तलाश में बेहतर होगा।

  1. java.util.Arrays
  • यह एक उपयोगिता वर्ग है जिसमें दिए गए एरे पर काम करने के लिए स्टैटिक विधियों का गुच्छा है
  • asList एक ऐसी स्थिर विधि है, जो इनपुट ऐरे को लेती है और java.util.Arrays.ArrayList का ऑब्जेक्ट लौटाती है, जो एक स्टैटिक नेस्टेड क्लास है, जो AbstractList को बढ़ाता है, जो सूची इंटरफ़ेस को लागू करता है।
  • तो Arrays.asList (inarray) इनपुट सरणी के चारों ओर एक सूची आवरण देता है, लेकिन यह आवरण java.util.Arrays.ArrayList है और java.util.ArrayList नहीं है और यह उसी सरणी को संदर्भित करता है ताकि सूची में लिपटे सरणी में अधिक तत्वों को जोड़ा जा सके। एक भी और हम भी लंबाई नहीं बदल सकते हैं।
  1. java.util.ArrayList
  • ArrayList में ओवरलोडेड कंस्ट्रक्टरों का झुंड है

    सार्वजनिक ArrayList () - // डिफ़ॉल्ट क्षमता 10 के साथ सरणी सूची देता है

    सार्वजनिक ArrayList (संग्रह c)

    सार्वजनिक एरेलेस्ट (इंट इनिशियल कैपासिटी)

  • इसलिए जब हम Arrays.asList पास वस्तु (लिस्ट) (AbstractList) को दूसरे कंस्ट्रक्टर के पास भेजते हैं, तो यह एक नया डायनामिक ऐरे बना देगा (यह ऐरे साइज़ बढ़ जाता है क्योंकि हम इसकी क्षमता से अधिक एलीमेंट जोड़ते हैं और नए एलिमेंट्स ऑरिजिनल ऐरे को भी प्रभावित नहीं करेंगे। ) उथले मूल सरणी की नकल करना ( उथली प्रतिलिपि का मतलब है कि यह केवल संदर्भों पर प्रतिलिपि बनाता है और समान वस्तुओं का एक नया सेट नहीं बनाता है जैसे कि संरेखित सरणी में)


4
String names[] = new String[]{"Avinash","Amol","John","Peter"};
java.util.List<String> namesList = Arrays.asList(names);

या

String names[] = new String[]{"Avinash","Amol","John","Peter"};
java.util.List<String> temp = Arrays.asList(names);         

उपरोक्त विवरण इनपुट सरणी पर आवरण जोड़ता है। तो सूची जोड़ने और हटाने जैसे तरीके सूची संदर्भ वस्तु 'नाम सूची' पर लागू नहीं होंगे।

यदि आप मौजूदा सरणी / सूची में एक तत्व जोड़ने का प्रयास करते हैं तो आपको "थ्रेड में अपवाद" मुख्य "java.lang.UnsupportedOperationException" मिलेगा।

उपरोक्त ऑपरेशन आसानी से या देखने के लिए है।
हम सूची ऑब्जेक्ट में जोड़ने या हटाने का कार्य नहीं कर सकते हैं। परंतु

String names[] = new String[]{"Avinash","Amol","John","Peter"};
java.util.ArrayList<String> list1 = new ArrayList<>(Arrays.asList(names));

या

String names[] = new String[]{"Avinash","Amol","John","Peter"};
java.util.List<String> listObject = Arrays.asList(names);
java.util.ArrayList<String> list1 = new ArrayList<>(listObject);

उपरोक्त कथन में आपने एक ArrayList वर्ग का एक ठोस उदाहरण बनाया है और एक सूची को एक पैरामीटर के रूप में पारित किया है।

इस मामले में विधि जोड़ना और हटाना ठीक से काम करेगा क्योंकि दोनों विधियाँ ArrayList वर्ग से हैं इसलिए यहाँ हमें कोई UnSupportedOperationException नहीं मिलेगी।
Arraylist ऑब्जेक्ट में किए गए परिवर्तन (एक सरणी सूची से / में एक तत्व को जोड़ने या हटाने के लिए) मूल java.util.List ऑब्जेक्ट को प्रतिबिंबित नहीं करेंगे।

String names[] = new String[] {
    "Avinash",
    "Amol",
    "John",
    "Peter"
};

java.util.List < String > listObject = Arrays.asList(names);
java.util.ArrayList < String > list1 = new ArrayList < > (listObject);
for (String string: list1) {
    System.out.print("   " + string);
}
list1.add("Alex"); //Added without any exception
list1.remove("Avinash"); //Added without any exception will not make any changes in original list in this case temp object.


for (String string: list1) {
    System.out.print("   " + string);
}
String existingNames[] = new String[] {
    "Avinash",
    "Amol",
    "John",
    "Peter"
};
java.util.List < String > namesList = Arrays.asList(names);
namesList.add("Bob"); // UnsupportedOperationException occur
namesList.remove("Avinash"); //UnsupportedOperationException

3

सबसे पहले एरेस वर्ग एक उपयोगिता वर्ग है जिसमें कोई नहीं है। एरेस पर काम करने के लिए उपयोगिता विधियाँ (एरेस वर्ग के लिए धन्यवाद, अन्यथा हमें धोखा देने वाली वस्तुओं पर कार्रवाई करने के लिए अपने तरीके बनाने की आवश्यकता होगी)

asList () विधि:

  1. asListविधि Arrayकक्षा की उपयोगिता विधियों में से एक है , यह स्थैतिक विधि है, इसलिए हम इस विधि को इसके वर्ग नाम (जैसे Arrays.asList(T...a)) से कह सकते हैं
  2. अब यहां ट्विस्ट है, कृपया ध्यान दें कि यह विधि नई ArrayListवस्तु नहीं बनाती है, यह सिर्फ मौजूदा Arrayऑब्जेक्ट के लिए एक सूची संदर्भ देता है (इसलिए अब asListविधि का उपयोग करने के बाद , मौजूदा Arrayऑब्जेक्ट के दो संदर्भ बनाए जाते हैं)
  3. और इस कारण से है, सभी तरीकों कि पर काम Listवस्तु, हो सकता है इस सरणी का उपयोग कर वस्तु पर काम नहीं Listकी तरह उदाहरण के लिए, संदर्भ Array, एस आकार लंबाई में तय हो गई है इसलिए आप स्पष्ट रूप से नहीं जोड़ सकते हैं या निकालें तत्वों से Arrayइस का उपयोग कर वस्तु Listकी तरह संदर्भ ( list.add(10)या list.remove(10);अन्यथा यह UnsupportedOperationException को फेंक देगा)
  4. सूची संदर्भ का उपयोग करके आप जो भी बदलाव कर रहे हैं, वह Arrayएस ऑब्जेक्ट से बाहर निकलने में परिलक्षित होगा (जैसा कि आप सूची संदर्भ का उपयोग करके मौजूदा एरे ऑब्जेक्ट पर काम कर रहे हैं)

पहले मामले में आप एक नई Arraylistवस्तु बना रहे हैं (दूसरे मामले में केवल मौजूदा ऐरे ऑब्जेक्ट का संदर्भ बनाया गया है, लेकिन एक नई ArrayListवस्तु नहीं है ), इसलिए अब दो अलग-अलग ऑब्जेक्ट हैं एक Arrayवस्तु है और दूसरा ArrayListऑब्जेक्ट नहीं है और उनके बीच कोई संबंध नहीं है (इसलिए परिवर्तन एक वस्तु में किसी अन्य वस्तु में परिलक्षित / प्रभावित नहीं होगा (जो कि 2 स्थिति में है Arrayऔर Arraylistदो अलग-अलग वस्तुएं हैं)

मामला एक:

Integer [] ia = {1,2,3,4};
System.out.println("Array : "+Arrays.toString(ia));
List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));  // new ArrayList object is created , no connection between existing Array Object
list1.add(5);
list1.add(6);
list1.remove(0);
list1.remove(0);
System.out.println("list1 : "+list1);
System.out.println("Array : "+Arrays.toString(ia));

मामला 2:

Integer [] ia = {1,2,3,4};
System.out.println("Array : "+Arrays.toString(ia));
List<Integer> list2 = Arrays.asList(ia); // creates only a (new ) List reference to existing Array object (and NOT a new ArrayList Object)
//  list2.add(5); //  it will throw java.lang.UnsupportedOperationException - invalid operation (as Array size is fixed)
list2.set(0,10);  // making changes in existing Array object using List reference - valid 
list2.set(1,11); 
ia[2]=12;     // making changes in existing Array object using Array reference - valid
System.out.println("list2 : "+list2);
System.out.println("Array : "+Arrays.toString(ia));

3

कई लोगों ने पहले से ही यांत्रिक विवरणों का जवाब दिया है, लेकिन यह ध्यान देने योग्य है: यह जावा द्वारा एक खराब डिजाइन विकल्प है।

जावा की asListविधि को "एक निश्चित आकार की सूची देता है ..." के रूप में प्रलेखित किया गया है । यदि आप इसका परिणाम लेते हैं और कॉल करते हैं (कहते हैं) .addविधि, यह एक फेंकता है UnsupportedOperationException। यह अचूक व्यवहार है! यदि कोई विधि कहती है कि यह एक रिटर्न देता है List, तो मानक अपेक्षा यह है कि वह एक ऑब्जेक्ट लौटाता है जो इंटरफ़ेस के तरीकों का समर्थन करता है List। एक डेवलपर को यह याद नहीं रखना चाहिए कि कौन- सी ऑमपेंटीन util.Listविधियां Listवास्तव में सभी Listविधियों का समर्थन नहीं करती हैं ।

यदि उन्होंने विधि का नाम asImmutableListदिया होता, तो इसका अर्थ होता। या अगर उनके पास सिर्फ एक वास्तविक तरीका था List(और बैकिंग ऐरे को कॉपी करें), तो यह समझ में आएगा। उन्होंने लिस्ट सरप्राइज के दोनों सिद्धांत और एस-ओओ से बचने के अच्छे-ओओ अभ्यास के उल्लंघन की कीमत पर रनटाइम-प्रदर्शन और लघु नामों के पक्ष में फैसला किया UnsupportedOperationException

(इसके अलावा, डिजाइनरों ने एक interface ImmutableList, UnsupportedOperationExceptionएस के ढेरों से बचने के लिए बनाया हो सकता है ।)


2

ध्यान दें कि, जावा 8 में, ऊपर 'ia' इंटेगर होना चाहिए [] और इंट [] नहीं। एक सरणी के Arrays.asList () एकल तत्व के साथ एक सूची देता है। ओपी के कोड स्निपेट का उपयोग करते समय, कंपाइलर समस्या को पकड़ लेगा, लेकिन कुछ विधियां (जैसे कलेक्शन.शफल) () चुपचाप आप जो उम्मीद करते हैं वह करने में विफल हो जाएंगे।


1
जब मैंने ArrayList <Integer> al = new ArrayList <Integer> (Arrays.asList (a)) किया तो मुझे इस संकलक मुद्दे का सामना करना पड़ा; जहाँ एक इंट [] था। मेरे अल को सिर्फ एक तत्व मिला है जो मुद्रित होने पर भी कचरा दिखता है। वह तत्व क्या है? और वहां आना कैसे होता है? मुझे जावा 7 में इस मुद्दे का सामना करना पड़ा
ज्योत्सना नंदवानी

@ ज्योत्सना नंदवाणी Pls मेरा जवाब देखें: stackoverflow.com/a/54105519/1163607
NINCOMPOOP

1
package com.copy;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class CopyArray {

    public static void main(String[] args) {
        List<Integer> list1, list2 = null;
        Integer[] intarr = { 3, 4, 2, 1 };
        list1 = new ArrayList<Integer>(Arrays.asList(intarr));
        list1.add(30);
        list2 = Arrays.asList(intarr);
        // list2.add(40); Here, we can't modify the existing list,because it's a wrapper
        System.out.println("List1");
        Iterator<Integer> itr1 = list1.iterator();
        while (itr1.hasNext()) {
            System.out.println(itr1.next());
        }
        System.out.println("List2");
        Iterator<Integer> itr2 = list2.iterator();
        while (itr2.hasNext()) {
            System.out.println(itr2.next());
        }
    }
}

1

Arrays.asList()

यह विधि List.It का अपना कार्यान्वयन लौटाती है। यह एक सरणी को एक तर्क के रूप में लेती है और इसके शीर्ष पर विधियों और विशेषताओं का निर्माण करती है, क्योंकि यह किसी सरणी से किसी डेटा की प्रतिलिपि नहीं बना रही है, लेकिन मूल सरणी का उपयोग करने से यह संशोधित होने पर मूल सरणी में परिवर्तन का कारण बनता है। Arrays.asList()विधि द्वारा दी गई सूची ।

दूसरी ओर। वर्ग
ArrayList(Arrays.asList()); का एक निर्माता है ArrayListजो एक सूची को तर्क के रूप में लेता है और एक सूची ArrayListसे स्वतंत्र होता है अर्थात। Arrays.asList()इस मामले में एक तर्क के रूप में पारित किया। यही कारण है कि आप इन परिणामों को देखते हैं;


0
1.List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));  //copy
2.List<Integer> list2 = Arrays.asList(ia);

पंक्ति 2 में, Arrays.asList(ia)अपने Listभीतर परिभाषित आंतरिक वर्ग की वस्तु का संदर्भ देता है Arrays, जिसे ArrayListनिजी भी कहा जाता है और केवल विस्तारित होता है AbstractList। इसका मतलब यह है कि जो लौटा है Arrays.asList(ia)वह एक वर्ग वस्तु है जो आपको मिलता है उससे अलग है new ArrayList<Integer>

आप पंक्ति 2 में कुछ ऑपरेशन का उपयोग नहीं कर सकते क्योंकि भीतर निजी वर्ग Arraysउन तरीकों को प्रदान नहीं करता है।

इस लिंक पर एक नज़र डालें और देखें कि आप निजी आंतरिक वर्ग के साथ क्या कर सकते हैं: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14-java/util/ Arrays.java # Arrays.ArrayList

पंक्ति 1 ArrayListआपको पंक्ति 2 से प्राप्त होने वाले तत्वों से एक नई वस्तु की प्रतिलिपि बनाता है । इसलिए आप java.util.ArrayListउन सभी तरीकों को प्रदान करने के बाद से जो चाहें कर सकते हैं ।


0

अंतर का सारांश -

जब नए ऑपरेटर Arrays.asList () पद्धति का उपयोग किए बिना सूची बनाई जाती है, तो इसका अर्थ होता है Wrapper

1. आप ऑपरेशन जोड़ / अद्यतन कर सकते हैं।

2. मूल सरणी में किए गए परिवर्तनों को सूची में और साथ ही इसके विपरीत परिलक्षित किया जाएगा।


0

जावा 8 के बाद से Arrays.asList () के व्यवहार के बारे में सवाल पूछने वाली कुछ टिप्पणियों के जवाब में :

    int[] arr1 = {1,2,3};
    /* 
       Arrays are objects in Java, internally int[] will be represented by 
       an Integer Array object which when printed on console shall output
       a pattern such as 
       [I@address for 1-dim int array,
       [[I@address for 2-dim int array, 
       [[F@address for 2-dim float array etc. 
   */
    System.out.println(Arrays.asList(arr1)); 

    /* 
       The line below results in Compile time error as Arrays.asList(int[] array)
       returns List<int[]>. The returned list contains only one element 
       and that is the int[] {1,2,3} 
    */
    // List<Integer> list1 = Arrays.asList(arr1);

    /* 
       Arrays.asList(arr1) is  Arrays$ArrayList object whose only element is int[] array
       so the line below prints [[I@...], where [I@... is the array object.
    */
    System.out.println(Arrays.asList(arr1)); 

    /* 
     This prints [I@..., the actual array object stored as single element 
     in the Arrays$ArrayList object. 
    */
    System.out.println(Arrays.asList(arr1).get(0));

    // prints the contents of array [1,2,3]
    System.out.println(Arrays.toString(Arrays.asList(arr1).get(0)));

    Integer[] arr2 = {1,2,3};
    /* 
     Arrays.asList(arr) is  Arrays$ArrayList object which is 
     a wrapper list object containing three elements 1,2,3.
     Technically, it is pointing to the original Integer[] array 
    */
    List<Integer> list2 = Arrays.asList(arr2);

    // prints the contents of list [1,2,3]
    System.out.println(list2);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.