Java.util.ArrayList शून्य जोड़ने की अनुमति क्यों देता है?


41

मुझे आश्चर्य है कि क्यों java.util.ArrayListजोड़ने की अनुमति देता है null। क्या कोई मामला है जहां मैं nullएक में जोड़ना चाहूंगा ArrayList?

मैं इस सवाल पूछ रहा हूँ क्योंकि एक परियोजना में हम एक बग जहां कुछ कोड जोड़ने था nullकरने के लिए ArrayListऔर यह पहचानना जहां बग था मुश्किल था। स्पष्ट रूप NullPointerExceptionसे फेंक दिया गया था लेकिन तब तक नहीं जब तक कि अन्य कोड ने तत्व तक पहुंचने की कोशिश नहीं की। समस्या यह थी कि nullऑब्जेक्ट को जोड़ने वाले कोड का पता कैसे लगाया जाए । यह आसान होता अगर ArrayListउस कोड में एक अपवाद फेंक दिया जाता जहां तत्वों को जोड़ा जा रहा था।


12
अमरूद परियोजना एक है उस विषय पर बहुत दिलचस्प पेज (वे अनुमति नहीं देते nullमें अपने संग्रह के सबसे)।
जोकिम सउर

6
मेरा मानना ​​है कि यहां दिए गए उत्तर प्रश्न को अच्छी तरह से कवर करते हैं। हो सकता है कि एक बात जिसका उल्लेख किया जाना चाहिए: जो कुछ भी जेडीके में होली और परफेक्ट के रूप में नहीं है, और फिर अपना सिर समझने की कोशिश करें कि यह "सही" क्यों है। कुछ चीजें (ईमानदार, IMHO) गलतियाँ हैं, जो कि पश्चगामी अनुकूलता के कारण बनी रहीं और वह है। यहां तक ​​कि जावा निर्माता इसे स्वीकार करते हैं, बस कुछ जावा एपीआई की आलोचना करने के लिए जोशुआ बलोच की किताबें पढ़ते हैं। किसी भी दर पर, आपका सवाल मौसम के अनुसार आता है, जावा में एनपीई को पकड़ने के लिए अधिक सुरुचिपूर्ण तरीका नहीं है। जवाब है, नहीं, लेकिन होना चाहिए।
शिवन ड्रैगन

2
क्या आप इस बारे में अधिक जानकारी प्रदान कर सकते हैं कि इसकी अनुमति क्यों नहीं दी जानी चाहिए? यदि यह सिर्फ स्वाद की बात है, तो कम प्रतिबंधक को प्राथमिकता दी जानी चाहिए।
घोड़ी इनफिनिटस

सरल जवाब सिर्फ इतना nullहै कि जावा में लापता डेटा का प्रतिनिधित्व करने का डिफ़ॉल्ट तरीका है, चाहे आप इसे पसंद करें या नहीं। वास्तव में बहुत से लोग इसे पसंद नहीं करते हैं और इसे कार्यात्मक प्रोग्रामिंग-शैली की चीजों के लिए तर्क बनाते हैं। सबसे उत्कीर्ण उत्तर कोई मतलब नहीं है / मुद्दे के सार पर कब्जा नहीं करता है।
xji

@ जियांगयांग आप देख रहे हैं कि क्या nullहै। "मिसिंग" कई संभावित व्याख्याओं में से एक है null। अन्य मान्य व्याख्याएं "अज्ञात," "लागू नहीं" या "अनधिकृत" हो सकती हैं। क्या nullप्रतिनिधित्व करता है आवेदन पर निर्भर करता है। जैसा कि पायथन समुदाय कहता है, "अस्पष्टता के सामने, अनुमान लगाने के प्रलोभन से इनकार करें।" एक कंटेनर में नल को पकड़ने से इनकार करना जो ऐसा करने में पूरी तरह से सक्षम है, बस इतना ही होगा - एक अनुमान।
रिवलॉक

जवाबों:


34

यह डिजाइन निर्णय ज्यादातर नामकरण द्वारा संचालित प्रतीत होता है।

नाम ArrayList पाठक को सरणियों के समान एक कार्यक्षमता का सुझाव देता है - और जावा कलेक्शंस फ्रेमवर्क डिजाइनरों के लिए यह उम्मीद करना स्वाभाविक है कि विशाल बहुमत एपीआई उपयोगकर्ता सरणियों के समान कार्य करने पर भरोसा करेंगे।

इसमें विशेष रूप से, अशक्त तत्वों का उपचार शामिल है। एपीआई उपयोगकर्ता यह जानकर कि नीचे काम करता है ठीक है:

array[0] = null; // NPE won't happen here

यह पता लगाने के लिए काफी आश्चर्य होगा कि क्या ArrayList के लिए समान कोड NPE फेंक देगा:

arrayList.set(0, null); // NPE => WTF?

ऊपर दिए गए तर्क जेसीएफ ट्यूटोरियल स्ट्रेसिंग पॉइंट्स में प्रस्तुत किए गए हैं जो कि ArrayList और सादे सरणियों के बीच घनिष्ठ समानता का सुझाव देते हैं:

ArrayList ... निरंतर-समय पर स्थिती प्रदान करता है और यह केवल सादा उपवास है ...

अगर आप सूची कार्यान्वयन को अशक्त करना चाहते हैं, तो बेहतर होगा NonNullableArrayListकि आप एपीआई उपयोगकर्ताओं को भ्रमित करने से बचें।


ध्यान दें कि नीचे दिए गए टिप्पणियों में एक सहायक चर्चा है, साथ ही यहां दिए गए तर्क का समर्थन करने वाले अतिरिक्त विचार हैं।


12
यह स्पष्टीकरण समझाने योग्य नहीं है, यह देखते हुए कि सूची प्रविष्टियों का LinkedList भी समर्थन करता है null
स्टीफन सी।

12
हाँ ... लेकिन एक सरल और (IMO) अधिक प्रशंसनीय स्पष्टीकरण यह है कि nullप्रविष्टियों को अनुमति देना बहुत सारे मामलों में उपयोगी है।
स्टीफन सी।

7
ArrayList को ऐसा नहीं कहा जाता है क्योंकि यह एक सरणी की नकल करता है। इसे ऐसा कहा जाता है क्योंकि यह एक सूची है जिसे एक सरणी के रूप में लागू किया गया है। जैसे एक TreeMap ट्री की तरह व्यवहार नहीं करता है।
फ्लोरियन एफ

11
यह उत्तर, IMO, केवल स्पष्ट गलत है। शून्य की अनुमति दी जाती है क्योंकि जावा में, बेहतर या बदतर के लिए, (IMO, बदतर) नल का उपयोग अनैतिक या लापता मूल्यों का प्रतिनिधित्व करने के लिए बहुत अधिक किया जाता है। इसे सबसे अधिक वोट और "स्वीकार" चेक कैसे मिला? सच में, मैं वास्तव में इन दिनों StackOverflow में विश्वास खो रहा हूँ।
user949300

8
यह उत्तर स्पष्ट गलत है। यह सूची क्रियान्वयन में अनुमति दी जा रही अशक्तता के बारे में सिर्फ असमर्थित अनुमान है। यहां जावा संग्रह का एक राउंडअप अनुमति देता है / नल को रोकना; ध्यान दें कि इसका सरणियों के साथ समानता से कोई लेना- देना नहीं है।
एंड्रेस एफ।

32

सूची के एक तत्व के लिए अशक्त मूल्य मान्य हो सकता है। मान लें कि आपकी सूची में ऐसे तत्व हैं जो उपयोगकर्ताओं की सूची के बारे में कुछ वैकल्पिक डेटा का प्रतिनिधित्व करते हैं और उपयोगकर्ताओं के समान क्रम में संग्रहीत होते हैं। यदि अतिरिक्त डेटा आबादी है तो आपकी सूची में अतिरिक्त डेटा होगा अन्यथा उपयोगकर्ता के अनुरूप स्लॉट शून्य होगा। (मुझे यकीन है कि बेहतर उदाहरण हैं, लेकिन आपको विचार मिलता है)

यदि आप नल को जोड़ने की अनुमति नहीं देना चाहते हैं, तो आप अपने स्वयं के आवरण के साथ सरणी सूची को लपेट सकते हैं जो कि नल को जोड़ा गया था।


2
ऐसा लगता है कि क्यों नल की अनुमति दी जानी चाहिए का एक बुरा उदाहरण है - सूची में अशक्त मानों का उपयोग करने की तुलना में वैकल्पिक डेटा का प्रतिनिधित्व करने के बेहतर तरीके हैं।
कैसाब्लांका

@ कासाब्लांका हाँ पूरी तरह से सहमत हैं, इसका एक महान उदाहरण नहीं है।
सैम होल्डर

मैं एक ArrayList को अशक्त करने के लिए एक अच्छा कारण नहीं मिल सकता है, फिर अगले डेवलपर के लिए यह 'खोज' के लिए बुरा आश्चर्य: /
AndreasScheinert

7
@ कासाब्लांका जबकि मैं आपसे सहमत हूं कि वैकल्पिक या डेटा के लिए जावा में, बेहतर या बदतर के लिए नल को बचा जाना चाहिए, जो "पारंपरिक" है।
user949300

2
एक ठोस उपयोग-मामला: आप कुछ डायनामिक फ़ंक्शन के मापदंडों को एक सूची के रूप में पारित करना चाहते हैं। आपके पास कई कार्य हैं, जिनमें से प्रत्येक पैरामीटर के एक अलग सेट के साथ है, इसलिए आपको गतिशील रूप से आकार की सरणी की आवश्यकता है और आप हमेशा एक मान्य सुरक्षा तर्क के रूप में अशक्त हो सकते हैं!
फाल्को

19

ArrayListडिजाइन द्वारा अशक्त होने की अनुमति देता है। यह जानबूझकर है। से जावाडोक :

"[ArrayList एक] सूची इंटरफ़ेस का resizable-array कार्यान्वयन है। सभी वैकल्पिक सूची कार्यों को लागू करता है, और सभी तत्वों को अनुमति देता है, जिसमें null भी शामिल है ।"

"क्यों" का उत्तर यह है कि अगर यह एरेलेस्ट उन मामलों में उपयोग करने योग्य नहीं होगा, जहां nullसूची में डालना आवश्यक है । इसके विपरीत, आप एक ArrayList को या तो परीक्षण करने से पहले मानों को जाँचने या आवरण का उपयोग करने वाले नल से युक्त होने से रोक सकते हैं जो ऐसा होने से रोकता है।

क्या कोई ऐसा मामला है जहां मैं एक ArrayList को अशक्त जोड़ना चाहूंगा?

जाहिर है, कोई भी मामला जहां nullएक अलग अर्थ रखता है। उदाहरण के लिए इसका मतलब यह हो सकता है कि सूची में दिए गए स्थान पर मूल्य को आरंभीकृत या आपूर्ति नहीं किया गया है।

यह आसान होता अगर ArrayList कोड में एक अपवाद फेंक देता जहाँ तत्व जोड़े जा रहे थे।

रैपर क्लास बनाकर आप उस व्यवहार को आसानी से लागू कर सकते हैं। हालाँकि, यह वह व्यवहार नहीं है जिसकी अधिकांश प्रोग्रामर / अनुप्रयोगों को आवश्यकता होती है।


8

क्या कोई ऐसा मामला है जहां मैं एक ArrayList को अशक्त जोड़ना चाहूंगा?

निश्चित रूप से, पूर्व-आवंटन के बारे में क्या? आप ArrayListऐसी चीजें चाहते हैं जो आप अभी तक नहीं बना सकते क्योंकि आपके पास पर्याप्त जानकारी नहीं है। सिर्फ इसलिए कि आप किसी कारण के बारे में नहीं सोच सकते हैं कि कोई ऐसा क्यों करना चाहता है जो इसे बुरा नहीं मानता। जो कुछ। (अब, मुझे यकीन है कि कोई व्यक्ति साथ आएगा और कहेगा कि आपके पास खाली वस्तुएं होनी चाहिए जो कुछ अस्पष्ट ब्लॉग पर पढ़े गए कुछ पैटर्न को पूरा करती हैं और प्रोग्रामर को वास्तव में कभी भी ifबयानों, ब्ला ब्ला का उपयोग किए बिना प्रोग्राम लिखने में सक्षम होना चाहिए ।)

यदि आप लोगों के पास एक अनुबंध है कि कभी भी nullकंटेनर में नहीं होना चाहिए, तो यह सुनिश्चित करने के लिए कि आप अनुबंधित है, यह सुनिश्चित करने के लिए बहुत कुछ है। यह संभवतः आपको कोड की अधिकतम 10 पंक्तियाँ ले गया होगा। जावा आपके लिए इस प्रकार का काम करना अविश्वसनीय रूप से आसान बनाता है। JDK आपके दिमाग को नहीं पढ़ सकता है।


1
आपका उपदेश तर्क अमान्य है, क्योंकि यह पहले से ही ArrayList में ensureCapacity(int minCapacity)विधि और ArrayList(int initialCapacity)निर्माता के साथ निर्मित है।
फिलिप

7
@Philipp उस स्पेस में क्या वैल्यूज़ होंगी?
जेम्स

स्पष्ट पसंद nullपूर्व-आवंटित (लेकिन अभी तक अप्रयुक्त ) की प्रविष्टियों में डालना है ArrayList; लेकिन हम ensureCapacityऐसा कर सकते हैं और फिर भी अन्य कार्यों को setकरने की अनुमति नहीं देते हैं । कहीं और दिए गए कारण मजबूत लगते हैं।
डेविड के

@ दाविद: यह कहना समझ में आता है कि setकिसी वस्तु के लिए किसी भी मूल्य पर संभव होना चाहिए, जिसे वापस किया जा सकता है get। भले ही उस getवस्तु के लिए एक सामान्य प्रयास जिसके लिए स्थान आवंटित किया गया था, लेकिन कभी नहीं लिखा गया था nullउसे वापस लौटने के बजाय एक अपवाद नहीं फेंकना चाहिए , फिर भी यह आवश्यक होगा कि उन तरीकों की एक जोड़ी हो जो list1.setOrEraseIfNull(index, list2.getOrReturnNull(index))आवश्यक होने के बजाय अनुमति देंif (list2.valueSet(index)) list1.set(index, list2.get(index)); else list1.unset(index);
सुपरकैट

1
@ दाविद: एक प्रविष्टि को पढ़ने का प्रयास किया गया है जिसे आवंटित किया गया है लेकिन अभी तक नहीं लिखा गया है या तो अशक्त होना चाहिए या अपवाद फेंक देना चाहिए; इसे वापस करना आसान है।
सुपरकैट

4

यह एक (सॉफ्टवेयर-) दार्शनिक प्रश्न यहाँ अधिक लगता है।

ArrayList उपयोगिता वर्ग के रूप में संभव उपयोग-मामलों की एक विस्तृत संदर्भ में सहायक होने के लिए डिज़ाइन किया गया है।

आपके छिपे हुए दावे के विपरीत कि वैध मान के रूप में नल को स्वीकार करना हतोत्साहित किया जाना चाहिए, ऐसे कई उदाहरण हैं जहां शून्य मान पूरी तरह से कानूनी है।

सबसे महत्वपूर्ण कारण यह है कि फ्रेमवर्क के प्रकार सहित किसी भी संदर्भ प्रकार nullके do not knowबराबर है। इसका तात्पर्य है कि nothingमूल्य के अधिक धाराप्रवाह संस्करण द्वारा किसी भी मामले में अशक्त को प्रतिस्थापित नहीं किया जा सकता है ।

तो, आपको अपनी सरणी सूची में Integers 1, 3, 7 को इसके संबंधित इंडेक्स पर संग्रहीत करने की सुविधा देता है: कुछ संगणना के कारण, आप तत्व को इंडेक्स 5 पर प्राप्त करना चाहते हैं, इसलिए आपका सरणी क्या लौटना चाहिए: "कोई मान संग्रहीत नहीं है"। यह रिटर्निंग नल या NullObject के जरिए हासिल किया जा सकता है । ज्यादातर मामलों में बिल्ट इन नाउल वैल्यू लौटाना काफी स्पष्ट है। एक विधि है कि कॉल करने के बाद कर सकते हैं अशक्त लौट सकते हैं और अपनी वापसी मान का उपयोग कर अशक्त के खिलाफ दिए गए मान का चेक आधुनिक कोड में काफी आम है।


4

बयान

File f = null;

वैध और उपयोगी है (मुझे नहीं लगता कि मुझे यह समझाने की आवश्यकता है कि क्यों)। इसी तरह फाइलों का संग्रह होना उपयोगी है, जिनमें से कुछ अशक्त हो सकते हैं।

List<File> files = new ArrayList<File>();
// use my collection of files
// ....
// not using this one anymore:
files.set(3, null);

संग्रह की उपयोगिता जिसमें शून्य वस्तुएं हो सकती हैं, उन वस्तुओं की उपयोगिता से सीधे आगे बढ़ती हैं, जो अशक्त हो सकती हैं। यह वास्तव में उतना ही सरल है।


2

प्रतिबंधात्मक होना और फिर तथ्य के बाद अपने डिजाइन को खोलने की कोशिश करना, सब कुछ स्वीकार करना आसान है।

उदाहरण के लिए, क्या होगा अगर वे / सूरज ने केवल नॉनएलेबलएरेएलिस्ट प्रदान किए, लेकिन आप अपनी सूची में एक नल जोड़ने में सक्षम होना चाहते थे। आपको इसे कैसे करना होगा? आपको संभवतः एक पूरी तरह से अलग वस्तु बनानी होगी, आप नॉन-वेजिटेबल एस्ट्रेलिस्ट का विस्तार नहीं कर सकते। इसके बजाय अगर आपके पास एक ArrayList है जो सब कुछ लेता है, तो आप इसे आसानी से बढ़ा सकते हैं, और ऐड को ओवरराइड कर सकते हैं, जहाँ यह अशक्त मूल्यों को स्वीकार नहीं करता है।


2
असहमत थे। एक बार मिसफिट्योर के व्यापक उपयोग को देखने के लिए बहुत अधिक मात्रा में सही करना कठिन है। यदि भाषा डिजाइनरों ने बाद के चरण में नल की अनुमति दी है, तो यह मौजूदा कार्यक्रमों को नहीं तोड़ पाएगा, लेकिन विपरीत सच नहीं है।
एंड्रेस एफ।

2
लेकिन मैं सहमत हूं। यह कार्यक्षमता को अधिकतम करने के बारे में है। आप एक सूची का उपयोग कर सकते हैं जो नल को स्वीकार करता है यहां तक ​​कि आपको उनकी आवश्यकता नहीं है। यदि आप nulls की आवश्यकता है, तो आप nulls को मना करने वाली सूची का उपयोग नहीं कर सकते।
फ्लोरियन एफ

-1

अशक्त की उपयोगिता?

जब आप विभिन्न पदों के साथ एक 2 डी वास्तविक जीवन की थाली को मॉडल करने के लिए सूचियों की सूची के साथ जाते हैं तो बहुत अधिक । उन पदों में से आधे खाली हो सकते हैं (यादृच्छिक निर्देशांक में) जबकि भरे हुए लोग एक साधारण इंट या स्ट्रिंग का प्रतिनिधित्व नहीं करते हैं लेकिन एक जटिल वस्तु द्वारा दर्शाए जाते हैं। यदि आप स्थिति की जानकारी रखना चाहते हैं, तो आपको रिक्त स्थानों को शून्य से भरने की आवश्यकता है ताकि आपकी सूची (x) .get (y) हो।बुरा आश्चर्य करने के लिए नेतृत्व नहीं करता है। अशक्त अपवादों का मुकाबला करने के लिए आप अशक्त (बहुत लोकप्रिय) की जांच कर सकते हैं या आप एक वैकल्पिक (जो मुझे इस मामले में उपयोगी लगते हैं) का उपयोग कर सकते हैं। विकल्प खाली स्थानों को "कबाड़" वस्तुओं के साथ भरना होगा, जिससे सड़क के नीचे सभी प्रकार की गंदगी हो सकती है। यदि आपका शून्य चेक विफल हो जाता है या कहीं भूल जाता है, तो जावा आपको बता देगा। दूसरी ओर एक "जंक" प्लेसहोल्डर ऑब्जेक्ट जिसे ठीक से चेक नहीं किया गया है, किसी का ध्यान नहीं जा सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.