जावा 9 ने सूचियों के लिए नए कारखाने के तरीके पेश किए List.of
:
List<String> strings = List.of("first", "second");
पिछले और नए विकल्प में क्या अंतर है? यही है, इस बीच क्या अंतर है:
Arrays.asList(1, 2, 3);
और इस:
List.of(1, 2, 3);
जावा 9 ने सूचियों के लिए नए कारखाने के तरीके पेश किए List.of
:
List<String> strings = List.of("first", "second");
पिछले और नए विकल्प में क्या अंतर है? यही है, इस बीच क्या अंतर है:
Arrays.asList(1, 2, 3);
और इस:
List.of(1, 2, 3);
जवाबों:
Arrays.asList
एक परस्पर सूची लौटाता है जबकि सूची द्वारा लौटाया जाता List.of
है अपरिवर्तनीय है :
List<Integer> list = Arrays.asList(1, 2, null);
list.set(1, 10); // OK
List<Integer> list = List.of(1, 2, 3);
list.set(1, 10); // Fails with UnsupportedOperationException
Arrays.asList
शून्य तत्वों को अनुमति List.of
नहीं देता है:
List<Integer> list = Arrays.asList(1, 2, null); // OK
List<Integer> list = List.of(1, 2, null); // Fails with NullPointerException
contains
नल के साथ अलग व्यवहार करता है:
List<Integer> list = Arrays.asList(1, 2, 3);
list.contains(null); // Returns false
List<Integer> list = List.of(1, 2, 3);
list.contains(null); // Fails with NullPointerException
Arrays.asList
पारित सरणी का एक दृश्य लौटाता है, इसलिए सरणी में परिवर्तन सूची में भी दिखाई देगा। के लिए List.of
यह सच नहीं है:
Integer[] array = {1,2,3};
List<Integer> list = Arrays.asList(array);
array[1] = 10;
System.out.println(list); // Prints [1, 10, 3]
Integer[] array = {1,2,3};
List<Integer> list = List.of(array);
array[1] = 10;
System.out.println(list); // Prints [1, 2, 3]
List.contains(Object o)
javadoc से : "फेंकता है [...] NullPointerException - यदि निर्दिष्ट तत्व शून्य है और यह सूची शून्य तत्वों (वैकल्पिक) की अनुमति नहीं देती है"। या इंटरफ़ेस के लेन-देन परिचय से जो कुछ पढ़ता है: "कुछ संग्रह कार्यान्वयन में उन तत्वों पर प्रतिबंध है जो उनके पास हो सकते हैं"
List.of
करता हैImmutableList
, इसका वास्तविक नाम सिर्फ गैर-सार्वजनिक कार्यान्वयन विवरण है। यदि यह सार्वजनिक था और किसी ने इसे List
फिर से डाला , तो अंतर कहां था? ऐसा अंतर कहां है Arrays.asList
, जो गैर-सार्वजनिक List
कार्यान्वयन लौटाता है, जो प्रयास करते समय add
या remove
, या उस सूची को छोड़ Collections.unmodifiableList
देता है, जिसके द्वारा वापस लौटा जाता है, जिसमें कोई संशोधन नहीं होता है? यह List
इंटरफ़ेस में निर्दिष्ट अनुबंधों के बारे में है। संग्रह वैकल्पिक तरीकों के साथ इंटरफेस हमेशा OOP जावा 1.2 के बाद से थे ...
Arrays.asList
और के बीच का अंतरList.of
JavaDocs देखें और स्टुअर्ट मार्क्स (या इसके पिछले संस्करण) द्वारा यह बात करें ।
मैं कोड उदाहरण के लिए निम्नलिखित का उपयोग करूंगा:
List<Integer> listOf = List.of(...);
List<Integer> asList = Arrays.asList(...);
List<Integer> unmodif = Collections.unmodifiableList(asList);
संरचनात्मक रूप से बदलने के किसी भी प्रयास का List.of
परिणाम होगा UnsupportedOperationException
। इसमें ऐड , सेट और रिमूव जैसे ऑपरेशन शामिल हैं । हालाँकि, आप सूची में ऑब्जेक्ट्स की सामग्री को बदल सकते हैं (यदि ऑब्जेक्ट अपरिवर्तनीय नहीं हैं), तो सूची "पूरी तरह से अपरिवर्तनीय" नहीं है।
के साथ बनाई गई unmodifiable सूचियों के लिए यह वही भाग्य है Collections.unmodifiableList
। केवल यह सूची मूल सूची का एक दृश्य है, इसलिए यदि आप मूल सूची को बदलते हैं तो यह बदल सकती है।
Arrays.asList
पूरी तरह से अपरिवर्तनीय नहीं है, इसमें कोई प्रतिबंध नहीं है set
।
listOf.set(1, "a"); // UnsupportedOperationException
unmodif.set(1, "a"); // UnsupportedOperationException
asList.set(1, "a"); // modified unmodif! unmodif is not truly unmodifiable
इसी तरह, बैकिंग ऐरे (यदि आप इसे पकड़ते हैं) को बदलने से लिस्ट बदल जाएगी।
संरचनात्मक अपरिहार्यता रक्षात्मक कोडिंग, संगामिति और सुरक्षा से संबंधित कई दुष्प्रभावों के साथ आती है जो इस उत्तर के दायरे से परे हैं।
List.of
और जावा 1.5 के बाद से कोई भी संग्रह null
एक तत्व के रूप में अनुमति नहीं देता है । null
एक तत्व या यहां तक कि एक लुकअप के रूप में पारित करने का प्रयास करने के परिणामस्वरूप होगा NullPointerException
।
चूंकि Arrays.asList
1.2 (संग्रह रूपरेखा) से एक संग्रह है, यह null
एस की अनुमति देता है ।
listOf.contains(null); // NullPointerException
unmodif.contains(null); // allowed
asList.contains(null); // allowed
चूंकि List.of
जावा 9 में पेश किया गया है और इस पद्धति द्वारा बनाई गई सूचियों का अपना (द्विआधारी) क्रमबद्ध रूप है, वे पहले के जेडीके संस्करणों (कोई बाइनरी संगतता ) पर deserialized नहीं किया जा सकता है । हालांकि, आप उदाहरण के लिए, JSON के साथ डी / सीरियल कर सकते हैं।
Arrays.asList
आंतरिक रूप से कॉल करता है new ArrayList
, जो संदर्भ असमानता की गारंटी देता है।
List.of
आंतरिक कार्यान्वयन पर निर्भर करता है। लौटे उदाहरणों में संदर्भ समानता हो सकती है, लेकिन चूंकि यह गारंटी नहीं है कि आप इस पर भरोसा नहीं कर सकते।
asList1 == asList2; // false
listOf1 == listOf2; // true or false
यह उल्लेख करते हुए कि सूचियाँ समान हैं (थ्रू List.equals
) यदि उनमें समान तत्व समान क्रम में हैं, तो इस बात की परवाह किए बिना कि वे कैसे बनाए गए थे या वे कौन से संचालन समर्थन करते हैं।
asList.equals(listOf); // true i.f.f. same elements in same order
यदि सूची में तत्वों की संख्या List.of
2 या उससे कम है, तो तत्वों को एक विशेष (आंतरिक) वर्ग के क्षेत्रों में संग्रहीत किया जाता है। एक उदाहरण वह सूची है जो 2 तत्वों (आंशिक स्रोत) को संग्रहीत करती है:
static final class List2<E> extends AbstractImmutableList<E> {
private final E e0;
private final E e1;
List2(E e0, E e1) {
this.e0 = Objects.requireNonNull(e0);
this.e1 = Objects.requireNonNull(e1);
}
}
अन्यथा वे एक समान रूप में एक सरणी में संग्रहीत होते हैं Arrays.asList
।
List.of
कार्यान्वयन करना, जिससे क्षेत्र के आधार पर (आकार <2) कर रहे हैं थोड़ा तेजी से कुछ कार्यों पर प्रदर्शन करते हैं। उदाहरण के लिए, size()
सरणी लंबाई को लाए बिना एक स्थिरांक लौटा सकता है, और contains(E e)
इसे ओवरहेड ओवरहेड की आवश्यकता नहीं होती है।
के माध्यम से एक unmodifiable सूची का निर्माण List.of
भी तेज है। उपर्युक्त कंस्ट्रक्टर की तुलना 2 संदर्भ असाइनमेंट (और तत्वों की मनमानी राशि के लिए भी) से करें
Collections.unmodifiableList(Arrays.asList(...));
जो 2 सूचियों और अन्य उपरि बनाता है। अंतरिक्ष के संदर्भ में, आप UnmodifiableList
रैपर के साथ-साथ कुछ पेनी भी बचाते हैं । अंततः, HashSet
समकक्ष में बचत अधिक ठोस होती है।
निष्कर्ष समय: उपयोग करें List.of
जब आप एक सूची चाहते हैं जो नहीं बदलती है और Arrays.asList
जब आप एक सूची चाहते हैं जो बदल सकती है (जैसा कि ऊपर दिखाया गया है)।
Arrays.asList
पूरी तरह से परस्पर नहीं है। asList.add(1);
फेंकता है UnsupportedOperationException
।
List.of
किसी भी समय उपयोग नहीं कर सकता लोगों को कॉल करने के लिए contains
और NullPointerException द्वारा आश्चर्यचकित नहीं होना चाहिए।
List.of और Arrays.asList के बीच अंतर को संक्षेप में बताएं
List.of
डेटा सेट कम और अपरिवर्तित होने पर सबसे अच्छा उपयोग किया जा सकता है, जबकि Arrays.asList
बड़े और गतिशील डेटा सेट के मामले में सबसे अच्छा उपयोग किया जा सकता है।
List.of
बहुत कम ओवरहेड स्थान लें क्योंकि इसका क्षेत्र-आधारित कार्यान्वयन है और कम हीप स्थान का उपभोग करता है, दोनों फिक्स्ड ओवरहेड के संदर्भ में और प्रति-तत्व आधार पर। Arrays.asList
अधिक ओवरहेड स्पेस लेते समय क्योंकि आरंभीकरण के दौरान यह ढेर में अधिक ऑब्जेक्ट बनाता है।
संग्रह द्वारा लौटाया गया List.of
अपरिवर्तनीय है और इसलिए थ्रेड-सेफ जबकि संग्रह द्वारा लौटाया जाने योग्य Arrays.asList
है और थ्रेड सुरक्षित नहीं है। (अपरिवर्तनीय संग्रह उदाहरण आम तौर पर अपने उत्परिवर्तनीय समकक्षों की तुलना में बहुत कम मेमोरी का उपभोग करते हैं।)
List.of
शून्य तत्वों की अनुमति नहीं देता है जबकि अशक्त तत्वों की Arrays.asList
अनुमति देता है।
Arrays.asList
बनाम के बारे में बात करते समय सच है List.of
, यह देखते हुए कि पूर्व में सचमुच एक सरणी के चारों ओर सिर्फ एक आवरण है। कम से कम OpenJDK के कार्यान्वयन में बहुत छोटे ओवरहेड दिखाई देते हैं। वास्तव में, List.of
पारित किसी भी सरणी की प्रतियां बनाने की आवश्यकता होगी, इसलिए जब तक कि सरणी खुद को जल्द ही GC'd नहीं जा रही है, ऐसा लगता है कि List.of
इसमें एक बड़ी मेमोरी फ़ुटप्रिंट है।
List.of(x)
और List.of(x, y)
अधिक कुशल हैं क्योंकि वे सरणियों को आवंटित नहीं करते हैं
List.of
हर बार नई सूचियों को वापस करने के लिए तरीकों की आवश्यकता नहीं होती है। इन सूचियों की एक अनिर्दिष्ट पहचान है, इसलिए जेवीसी स्तर पर संभाला जा सकता है। यदि इस संस्करण में नहीं है, तो शायद अगले में। यह अनुबंध द्वारा अनुमत है। इसके विपरीत, Array.asList
आप जिस ऐरे से गुजर रहे हैं, उसकी पहचान पर निर्भर करता है, क्योंकि परिणामस्वरूप सूची एरे पर देखने योग्य है, जो सभी को अप्रत्यक्ष रूप से बदलते हुए दर्शाती है।
उपर्युक्त उत्तरों के अलावा कुछ निश्चित कार्य हैं, जिन पर दोनों अलग List::of
- Arrays::asList
अलग हैं:
+----------------------+---------------+----------+----------------+---------------------+
| Operations | SINGLETONLIST | LIST::OF | ARRAYS::ASLIST | JAVA.UTIL.ARRAYLIST |
+----------------------+---------------+----------+----------------+---------------------+
| add | ❌ | ❌ | ❌ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| addAll | ❌ | ❌ | ❌ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| clear | ❌ | ❌ | ❌ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| remove | ❌ | ❌ | ❌ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| removeAll | ❗️ | ❌ | ❗️ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| retainAll | ❗️ | ❌ | ❗️ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| replaceAll | ❌ | ❌ | ✔️ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| set | ❌ | ❌ | ✔️ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| sort | ✔️ | ❌ | ✔️ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| remove on iterator | ❌ | ❌ | ❌ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
| set on list-iterator | ❌ | ❌ | ✔️ | ✔️ |
+----------------------+---------------+----------+----------------+---------------------+
संग्रह के बारे में अधिक जानकारी :: singletonList Vs. की सूची