जावा कलेक्शंस सीधे प्रिमिटिव प्रकारों को स्टोर क्यों नहीं कर सकते हैं?


123

जावा संग्रह केवल वस्तुओं को संग्रहीत करता है, न कि आदिम प्रकार; हालाँकि हम रैपर कक्षाओं को स्टोर कर सकते हैं।

यह अड़चन क्यों?


2
यह बाधा तब चूसना करती है जब आप आदिम से निपटते हैं और भेजने के लिए क्यू का उपयोग करना चाहते हैं और आपके भेजने की दर बहुत तेज है। मैं उस मुद्दे से निपट रहा हूं जिसमें अभी बहुत ज्यादा समय लग रहा है।
जेपीएम

तकनीकी रूप से, आदिम प्रकार की वस्तुएं हैं (सटीक होने के लिए एकल उदाहरण), वे सिर्फ classजेवीएम द्वारा परिभाषित नहीं हैं । यह कथन int i = 1उस वस्तु के सिंगलटन उदाहरण के लिए एक संकेतक को परिभाषित करता intहै जो जेवीएम में परिभाषित होता है, जेवीएम 1में कहीं निर्धारित मूल्य पर सेट होता है । हां, जावा में संकेत - यह भाषा कार्यान्वयन द्वारा आपसे केवल दूर है। प्रिमिटिव्स को जेनेरिक के रूप में इस्तेमाल नहीं किया जा सकता है क्योंकि भाषा सभी सामान्य प्रकारों की भविष्यवाणी करती है जो सुपरटेप की होनी चाहिए Object- इसलिए रन-टाइम पर A<?>संकलन क्यों A<Object>
रॉबर्ट ई फ्राई

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

जवाबों:


99

यह एक जावा डिजाइन निर्णय था, और एक कि कुछ एक गलती मानते हैं। कंटेनर चाहते हैं कि ऑब्जेक्ट और प्राइमिटिव ऑब्जेक्ट से न निकले।

यह एक जगह है जो .NET डिजाइनरों ने जेवीएम से सीखी और मूल्य प्रकार और जेनेरिक को लागू किया जैसे कि कई मामलों में बॉक्सिंग को समाप्त कर दिया जाता है। सीएलआर में, सामान्य कंटेनर अंतर्निहित कंटेनर संरचना के भाग के रूप में मूल्य प्रकारों को संग्रहीत कर सकते हैं।

जावा ने जेवीएम के समर्थन के बिना कंपाइलर में सामान्य समर्थन 100% जोड़ने का विकल्प चुना। जेवीएम वह है जो "गैर-वस्तु" ऑब्जेक्ट का समर्थन नहीं करता है। जावा जेनरिक आपको दिखावा करने की अनुमति देता है कि कोई आवरण नहीं है, लेकिन आप अभी भी मुक्केबाजी के प्रदर्शन मूल्य का भुगतान करते हैं। कार्यक्रमों के कुछ वर्गों के लिए यह महत्वपूर्ण है।

मुक्केबाजी एक तकनीकी समझौता है, और मुझे लगता है कि यह भाषा में लीक हो रहा कार्यान्वयन विस्तार है। ऑटोबॉक्सिंग अच्छा सिंटैक्टिक शुगर है, लेकिन अभी भी एक प्रदर्शन दंड है। अगर कुछ भी हो, तो मुझे ऑटोबॉक्स होने पर मुझे चेतावनी देने के लिए कंपाइलर चाहिए। (सभी के लिए मुझे पता है, यह अब हो सकता है, मैंने यह जवाब 2010 में लिखा था)।

बॉक्सिंग के बारे में SO पर एक अच्छी व्याख्या: कुछ भाषाओं को बॉक्सिंग और अनबॉक्सिंग की आवश्यकता क्यों है?

और जावा जेनरिक की आलोचना: कुछ लोग क्यों दावा करते हैं कि जावा का जेनेरिक कार्यान्वयन खराब है?

जावा के बचाव में, पीछे की ओर देखना और आलोचना करना आसान है। जेवीएम ने समय की कसौटी पर कस दिया है, और कई मामलों में एक अच्छा डिज़ाइन है।


6
एक गलती नहीं है, एक सावधानी से चुना हुआ ट्रेडऑफ जो मुझे विश्वास है कि वास्तव में जावा की बहुत अच्छी तरह से सेवा की है।
डीजेकेवर्थ

13
यह एक गलती थी जो .NET ने इसे सीखा और शुरू से ऑटोबॉक्सिंग लागू किया, और बिना ओवरहेड बॉक्सिंग के वीएम स्तर पर जेनरिक। एक सुधार पर जावा का स्वयं का प्रयास केवल एक सिंटैक्स स्तर का समाधान था जो अभी भी ऑटोबॉक्सिंग बनाम प्रदर्शन के हिट से ग्रस्त है, कोई मुक्केबाजी नहीं। जावा के कार्यान्वयन ने बड़े डेटा संरचनाओं के साथ खराब प्रदर्शन दिखाया है।
कोडेनहेम

2
@mrjoltcola: IMHO, डिफ़ॉल्ट ऑटोबॉक्सिंग एक गलती है, लेकिन चर और मापदंडों को टैग करने का एक तरीका होना चाहिए था जो स्वचालित रूप से उन्हें दिए गए मूल्यों को बॉक्स करना चाहिए। अब भी, मुझे लगता है कि यह निर्दिष्ट करने के लिए एक साधन जोड़ा जाना चाहिए कि कुछ चर या मापदंडों को नव-ऑटो-बॉक्स वाले मानों को स्वीकार नहीं करना चाहिए [जैसे कि बॉक्स के पूर्णांक को पहचानने वाले Object.ReferenceEqualsप्रकार के संदर्भों को पारित करना कानूनी होना चाहिए Object, लेकिन यह कानूनी नहीं होना चाहिए एक पूर्णांक मान पास करें]। जावा का ऑटो-अनबॉक्सिंग IMHO सिर्फ गंदा है।
सुपरकाट

18

कार्यान्वयन को आसान बनाता है। चूंकि जावा प्राइमिटिव्स को ऑब्जेक्ट नहीं माना जाता है, इसलिए आपको इनमें से प्रत्येक प्राइमेटिक्स (साझा करने के लिए कोई टेम्पलेट कोड नहीं) के लिए एक अलग संग्रह वर्ग बनाने की आवश्यकता होगी।

आप बस जीएनयू ट्रोव को देख सकते हैं , अपाचे कॉमन्स प्राइमेटीज या एचपीपीसी देखें

जब तक आपके पास वास्तव में बड़े संग्रह हैं, रैपरों के लिए ओवरहेड लोगों के लिए देखभाल करने के लिए पर्याप्त मायने नहीं रखता है (और जब आपके पास वास्तव में बड़े आदिम संग्रह हैं, तो आप उनके लिए एक विशेष डेटा संरचना का उपयोग / निर्माण करने के लिए प्रयास करने में खर्च करना चाह सकते हैं। )।


11

यह दो तथ्यों का एक संयोजन है:

  • जावा आदिम प्रकार संदर्भ प्रकार नहीं हैं (उदाहरण के लिए ए intनहीं हैObject )
  • जावा संदर्भ प्रकारों के प्रकार-विलोपन का उपयोग करते हुए जेनेरिक करता है (जैसे List<?>कि वास्तव में एक List<Object>रन-टाइम है)

चूंकि ये दोनों सच हैं, जेनेरिक जावा संग्रह सीधे आदिम प्रकारों को संग्रहीत नहीं कर सकते हैं। सुविधा के लिए, आदिम प्रकारों को स्वचालित रूप से संदर्भ प्रकारों के रूप में बॉक्स करने की अनुमति देने के लिए ऑटोबॉक्सिंग पेश किया जाता है। इसके बारे में कोई गलती न करें, हालांकि, संग्रह अभी भी परवाह किए बिना ऑब्जेक्ट संदर्भ संग्रहीत कर रहे हैं।

क्या इससे बचा जा सकता था? शायद।

  • यदि intObject , तो बॉक्स प्रकारों की कोई आवश्यकता नहीं है।
  • यदि जेनेरिक टाइप-इरेज़र का उपयोग नहीं किया जाता है, तो प्राइमिटिव्स का उपयोग टाइप मापदंडों के लिए किया जा सकता है।

8

ऑटो-बॉक्सिंग और ऑटो-अनबॉक्सिंग की अवधारणा है । यदि आप जावा कंपाइलर intमें स्टोर करने का प्रयास करते हैं, तो List<Integer>यह स्वचालित रूप से इसे एक में बदल देगा Integer


1
जेनरिक के साथ जावा 1.5 में ऑटोबॉक्सिंग पेश किया गया था।
जेरेमी

1
लेकिन इसकी एक संकलन समय बात; प्रदर्शन लाभ के बिना वाक्य रचना चीनी। जावा कंपाइलर ऑटोबॉक्स होता है, इसलिए वीएम कार्यान्वयन की तुलना में प्रदर्शन जुर्माना। जैसे कि नेटिक्स में बॉक्सिंग शामिल नहीं है।
कोडेनहेम

1
@ मृजोलटकोला: आपकी बात क्या है? मैं सिर्फ तथ्य साझा कर रहा था, एक तर्क नहीं बना रहा था।
जेरेमी

3
सिंटैक्स और प्रदर्शन के बीच अंतर को इंगित करने के लिए मेरा बिंदु महत्वपूर्ण है। मैं अपनी टिप्पणियों को तथ्य-साझा करने पर भी विचार करता हूं, तर्क पर नहीं। धन्यवाद।
कोडेनहेम

2

यह वास्तव में एक बाधा नहीं है?

विचार करें कि क्या आप एक संग्रह बनाना चाहते हैं जो आदिम मूल्यों को संग्रहीत करता है। आप एक संग्रह कैसे लिखेंगे जो इंट, या फ्लोट या चार को स्टोर कर सकता है? सबसे अधिक संभावना है कि आप कई संग्रह के साथ समाप्त हो जाएंगे, इसलिए आपको एक इंटलिस्ट और एक चार्जलिस्ट आदि की आवश्यकता होगी।

जावा के ऑब्जेक्ट ओरिएंटेड नेचर का फायदा उठाते हुए जब आप कलेक्शन क्लास लिखते हैं तो वह किसी भी ऑब्जेक्ट को स्टोर कर सकता है इसलिए आपको केवल एक कलेक्शन क्लास की जरूरत होती है। यह विचार, बहुरूपता बहुत शक्तिशाली है और पुस्तकालयों के डिजाइन को बहुत सरल करता है।


7
"आप एक संग्रह कैसे लिखेंगे जो इंट, या फ्लोट या चार को स्टोर कर सकता है?" - अन्य भाषाओं की तरह ठीक से लागू किए गए जेनरिक / टेम्प्लेट के साथ जो हर चीज का ढोंग करने का दंड नहीं देते हैं, एक वस्तु है।
कोडेनहेम

मैंने शायद ही कभी छह साल में जावा को आदिम संग्रह एकत्र करना चाहता था। यहां तक ​​कि कुछ मामलों में जहां मैं संदर्भ वस्तुओं का उपयोग करने के लिए अतिरिक्त समय और स्थान की लागत चाहता था, नगण्य रहा है। विशेष रूप से मुझे पता है कि बहुत से लोग सोचते हैं कि वे मानचित्र <int, T> चाहते हैं, यह भूलकर कि एक सरणी उस चाल को बहुत अच्छी तरह से करेगी।
डीजेकेवर्थ

2
@DJClayworth यदि केवल महत्वपूर्ण मान गैर-विरल हैं, तो यह अच्छी तरह से काम करता है। बेशक, आप चाबियों पर नज़र रखने के लिए एक सहायक सरणी का उपयोग कर सकते हैं, लेकिन इसके अपने मुद्दे हैं: अपेक्षाकृत कुशल पहुंच को द्विआधारी खोज की अनुमति देने के लिए महत्वपूर्ण आदेश के आधार पर दोनों सरणियों को रखने की आवश्यकता होगी, जो बदले में सम्मिलन और विलोपन करेगी। जब तक सम्मिलन / विलोपन को अक्षम नहीं किया जाता है, तब तक डाला जाता है कि सम्मिलित आइटम समाप्त होने की संभावना है, जहां पहले हटाए गए आइटम थे और / या कुछ बफ़र्स को सरणियों में इंटरसेप्टर किया गया था, आदि संसाधन उपलब्ध हैं, लेकिन इसमें होना अच्छा होगा जावा ही।
JAB

@JAB वास्तव में यह ठीक काम करता है यदि चाबियाँ विरल हैं, तो उन्हें स्पार्स नहीं होने की तुलना में अधिक मेमोरी की आवश्यकता होती है। और अगर वे चाबियां विरल हैं, तो इसका मतलब है कि उनमें से कई नहीं हैं और एक महत्वपूर्ण कार्य के रूप में इंटेगर का उपयोग कर रहे हैं। जो भी दृष्टिकोण कम से कम स्मृति का उपयोग करें। या जो भी आपको लगता है अगर आपको परवाह नहीं है।
डीजेकेवर्थ

0

मुझे लगता है कि हम इस स्पेस में JDK में संभवतः जावा 10 में इस JEP के आधार पर प्रगति देख सकते हैं - http://openjdk.java.net/jeps/218

यदि आप आज संग्रह में मुक्केबाजी की प्रधानता से बचना चाहते हैं, तो कई तृतीय पक्ष विकल्प हैं। पहले उल्लिखित तीसरे पक्ष के विकल्पों के अलावा, एक्लिप्स कलेक्शन , फास्टटिल और कोलोबोक भी है

शीर्षक के साथ कुछ समय पहले आदिम नक्शों की तुलना भी प्रकाशित की गई थी: बड़े हैशपॉव अवलोकन: जेडीके, फास्टटिल, गोल्डमैन सैक्स, एचपीपीसी, कोलोबोक, ट्रोव । जीएस कलेक्शंस (गोल्डमैन सैक्स) पुस्तकालय को ग्रहण फाउंडेशन में स्थानांतरित कर दिया गया था और अब ग्रहण संग्रह है।


0

मुख्य कारण जावा डिजाइन रणनीति है। ++ 1) संग्रह में हेरफेर के लिए वस्तुओं की आवश्यकता होती है और आदिम वस्तु से व्युत्पन्न नहीं होते हैं इसलिए यह दूसरा कारण हो सकता है। 2) जावा आदिम डेटा प्रकार पूर्व के लिए संदर्भ प्रकार नहीं हैं। int कोई वस्तु नहीं है।

काबू पाना:-

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

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