जावा वेक्टर (और स्टैक) वर्ग को अप्रचलित या पदावनत क्यों माना जाता है?


677

जावा वेक्टर को एक विरासत वर्ग माना जाता है, अप्रचलित या पदावनत?

संगामिति के साथ काम करते समय क्या इसका उपयोग मान्य नहीं है?

और अगर मैं वस्तुओं को मैन्युअल रूप से सिंक्रनाइज़ नहीं करना चाहता हूं और बस अंतर्निहित सरणी (जैसा कि CopyOnWriteArrayListकरता है) की नई प्रतियां बनाने की आवश्यकता के बिना थ्रेड-सुरक्षित संग्रह का उपयोग करना चाहता हूं , तो क्या इसका उपयोग करना ठीक है Vector?

किस बारे में Stack, जो एक उपवर्ग है Vector, मुझे इसके बजाय क्या उपयोग करना चाहिए?


वे अप्रचलित हैं, लेकिन वे पदावनत नहीं हैं।
Lorne

जवाबों:


655

Vectorप्रत्येक व्यक्तिगत ऑपरेशन पर सिंक्रनाइज़ करता है। यह लगभग कभी नहीं है कि आप क्या करना चाहते हैं।

आम तौर पर आप संचालन के एक पूरे अनुक्रम को सिंक्रनाइज़ करना चाहते हैं । व्यक्तिगत संचालन को सिंक्रनाइज़ करना दोनों कम सुरक्षित है (यदि आप Vectorउदाहरण के लिए, इस पर पुनरावृति करते हैं , तो आपको उसी समय संग्रह को बदलने से किसी और से बचने के लिए ताला निकालने की आवश्यकता होती है, जो ConcurrentModificationExceptionपुनरावृति धागे में एक कारण होगा ) लेकिन धीमी भी ( क्यों बार-बार ताला हटाओगे जब एक बार पर्याप्त होगा)?

बेशक, इसमें लॉकिंग का ओवरहेड भी है, जब आपको ज़रूरत नहीं है।

मूल रूप से, यह ज्यादातर स्थितियों में सिंक्रनाइज़ेशन के लिए एक बहुत ही त्रुटिपूर्ण दृष्टिकोण है। जैसा कि श्री ब्रायन हेंक ने बताया है, आप कॉल का उपयोग करके एक संग्रह को सजा सकते हैं जैसे Collections.synchronizedList- यह तथ्य कि Vector"रिसाइज्ड सरणी" संग्रह कार्यान्वयन दोनों को "हर ऑपरेशन को सिंक्रनाइज़ करें" बिट के साथ संयोजन करता है, खराब डिजाइन का एक और उदाहरण है; सजावट दृष्टिकोण क्लीनर को चिंताओं से अलग करता है।

एक के रूप में Stackबराबर - मैं देखो चाहते हैं Deque/ ArrayDequeके साथ शुरू करने के लिए।


108
"आम तौर पर आप संचालन के एक पूरे अनुक्रम को सिंक्रनाइज़ करना चाहते हैं।" - मुद्दा यह है! धन्यवाद!
fjsj

7
जावा के किस संस्करण में डीप्रेकेटेड वेक्टर (वर्तमान में मैंने जावा 7 का उपयोग किया है)। लेकिन क्या मुझे कभी डिप्रेस्ड के रूप में नहीं देखा जाता है? बाय द वे वे नाइस
एक्सप्लोरेशन

17
@ आमिर: यह आधिकारिक तौर पर पदावनत नहीं है - यह सिर्फ इतना है कि एरियरिस्ट को आमतौर पर पसंद किया जाता है।
जॉन स्कीट

26
@ आमिर: नहीं, मैं भविष्य की भविष्यवाणी करने की कोशिश नहीं कर रहा हूं।
जॉन स्कीट

5
बस जी 8। वेक्टर पदावनत नहीं है इसकी एक विरासत class.There पदावनत और विरासत और हाँ वहाँ है देखने के बीच का अंतर होना चाहिए stackoverflow.com/questions/2873254/...
प्रशांत Shilimkar

82

वेक्टर 1.0 का हिस्सा था - मूल कार्यान्वयन में दो कमियां थीं:

1. नामकरण: वैक्टर वास्तव में केवल सूचियां हैं जिन्हें सरणियों के रूप में एक्सेस किया जा सकता है, इसलिए इसे बुलाया जाना चाहिए था ArrayList(जो कि जावा 1.2 संग्रह प्रतिस्थापन है Vector)।

2. संगामिति: सभी get(), set()विधियाँ हैं synchronized, इसलिए आप सिंक्रनाइज़ेशन पर ठीक से नियंत्रण नहीं कर सकते हैं।

ArrayListऔर के बीच बहुत अंतर नहीं है Vector, लेकिन आपको उपयोग करना चाहिए ArrayList

एपीआई डॉक्टर से।

जावा 2 प्लेटफॉर्म v1.2 के रूप में, इस वर्ग को सूची इंटरफ़ेस को लागू करने के लिए रेट्रोफिट किया गया था, जो इसे जावा कलेक्शंस फ्रेमवर्क का सदस्य बनाता है। नए संग्रह कार्यान्वयन के विपरीत, वेक्टर सिंक्रनाइज़ किया गया है।


सूचियाँ जो सरणियों के रूप में एक्सेस की जा सकती हैं? ArrayList एक बहुत छोटा या आकर्षक नाम नहीं है, जो हो सकता है कि वेक्टर का उपयोग कहीं और किया जाए (जैसे STL)।
dhardy

6
@ अंतर्निहित कार्यान्वयन के रूप में एक सरणी के साथ सूची। नहीं है ArrayList, LinkedListजो सभी के इंटरफ़ेस को लागू, आदि, List, इसलिए यदि आप उपयोग करना चाहते हैं Listपता करने के लिए अंतर्निहित कार्यान्वयन वास्तव में है क्या तुम सिर्फ एक ले जा सकते हैं बिना तरीकों Listआदि तरीकों के लिए एक पैरामीटर, उसी के कार्यान्वयन के लिए लागू होता है के रूप में Mapऔर इसी तरह। इस बीच, सी ++ में एक std::arrayवर्ग होता है, जो सी-स्टाइल स्टेटिक लंबाई सरणियों के लिए सिर्फ एक टेम्पलेट-आधारित प्रतिस्थापन है।
JAB

41

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


14

आप गैर-थ्रेड-सुरक्षित से थ्रेड-सुरक्षित संग्रह प्राप्त करने के लिए सिंक्रोनाइज़ेशन / सूची विधि का उपयोग कर सकते हैं java.util.Collection


2
यह वेक्टर से बेहतर क्यों है?
fjsj

8
जैसा कि जॉन ने उल्लेख किया है, वेक्टर भी उतना अच्छा प्रदर्शन नहीं करेगा, और यह विधि आपको यह चुनने की अनुमति देती है कि इसका अच्छा विचार सिंक्रनाइज़ेशन करने के लिए कब होगा। यह पूरी तरह से एक डिजाइन मुद्दा है। आपको वेक्टर पर ArrayList का उपयोग करना चाहिए क्योंकि आपको गैर-सिंक्रनाइज़ किए गए एक्सेस के लिए डिफ़ॉल्ट होना चाहिए।
ब्रायन हेंक

यह प्रश्न का उत्तर कैसे देता है?
Lorne

8

java.util.Stackका सिंक्रनाइज़ेशन ओवरहेड विरासत में मिला है java.util.Vector, जो आमतौर पर उचित नहीं है।

यह उससे बहुत अधिक विरासत में मिला है, हालांकि। तथ्य यह java.util.Stack extends java.util.Vectorहै कि वस्तु उन्मुख डिजाइन में एक गलती है। शुद्धतावादी ध्यान देंगे कि यह पारंपरिक रूप से एक स्टैक से जुड़े ऑपरेशन (अर्थात्: धक्का, पॉप, झांकना, आकार) से परे कई तरीके प्रदान करता है। यह भी करने के लिए संभव है search, elementAt, setElementAt, remove, और कई अन्य यादृच्छिक अभिगम आपरेशनों। यह मूल रूप से उपयोगकर्ता पर निर्भर है कि वह गैर-स्टैक संचालन के उपयोग से बचना चाहिए Stack

इन प्रदर्शनों और OOP डिज़ाइन कारणों के लिए, JavaDocjava.util.StackArrayDeque प्राकृतिक प्रतिस्थापन के रूप में सिफारिश करता है। (एक स्टैक एक स्टैक से अधिक है, लेकिन कम से कम यह दो सिरों को हेरफेर करने के लिए प्रतिबंधित है, बजाय सब कुछ यादृच्छिक पहुंच प्रदान करने के लिए।)

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