2012-09-07 15 views
48

इन दो घोषणाओं के बीच क्या अंतर है?जावा में ArrayList या सूची घोषणा

घोषणा 1:

ArrayList<String> arrayList = new ArrayList<String>(); 

घोषणा 2:

List<String> arrayList = new ArrayList<String>(); 
+1

के संभावित डुप्लिकेट उनके इंटरफेस द्वारा वस्तुओं को देखें [क्यों कोडिंग "इंटरफ़ेस में" विशेष रूप से आदिम डेटाटाइप के लिए होनी चाहिए?] (http://stackoverflow.com/questions/9392813/why-the-coding-should-be-to-the-interface- विशेष रूप से-for-primitive- डेटाटाइप) – assylias

+0

था एक भी है: http://stackoverflow.com/questions/1413543/what-does-it-mean-to-program-to-a-interface – assylias

+0

http://stackoverflow.com/questions/3383726/ पर एक नज़र डालें जावा-घोषणा-से-इंटरफ़ेस-प्रकार-बदले के वर्ग – Maciej

उत्तर

48
List<String> arrayList = new ArrayList<String>(); 

सामान्य है जहां जबकि, ग्राहक को लौटने का बाद में किसी समय कार्यान्वयन विवरण छुपाना चाहते हैं समय आप ArrayList सेसे कार्यान्वयन बदल सकते हैंपारदर्शी रूप से।

यह तंत्र उन मामलों में उपयोगी है जहां आप लाइब्रेरी आदि तैयार करते हैं, जो कुछ समय पर ग्राहक कार्यान्वयन के विवरणों को बदल सकते हैं।

ArrayList<String> arrayList = new ArrayList<String>(); 

यह आपको जनादेश हमेशा ArrayList लौटना ही होगा। कुछ समय पर यदि आप LinkedList पर कार्यान्वयन विवरण बदलना चाहते हैं, तो ArrayList के बजाय LinkedList का उपयोग करने के लिए ग्राहक पक्ष में भी बदलाव होना चाहिए।

+2

और संग्रह वर्ग पूरी तरह से सूची इंटरफ़ेस के साथ काम नहीं करता है, इसलिए Collections.emptyList, Collections.synchronizedList Collections.unmodifiable जैसी चीजें सभी वापसी सूची सूचीबद्ध करें। इसलिए यदि कोई एपीआई ArrayList की अपेक्षा करता है, तो आप भाग्य से बाहर हैं यदि आप इन विधियों के साथ मौजूदा सूची को लपेटना चाहते हैं। – Matt

+0

_input_ पैरामीटर के लिए, निश्चित रूप से, मैं सहमत हूं, लेकिन यह विपरीत के बारे में है; अर्थात्, वस्तु _instantiation_। इस मामले में, _only_ चीज यह करता है कि सभी ArrayList- विशिष्ट फ़ंक्शंस को हटा दें जो _should_ आपके लिए उपलब्ध हो। – Nyerguds

+0

"यह जनादेश आपको हमेशा ArrayList वापस करने की आवश्यकता है" पूरी तरह गलत है। आप पूरी तरह से अपने रिटर्न प्रकार 'सूची' को पूरी तरह से बना सकते हैं, इससे कोई फर्क नहीं पड़ता कि आप आंतरिक रूप से क्या उपयोग करते हैं। – Nyerguds

1

सूची इंटरफ़ेस है और ऐरेलिस्ट को ठोस वर्ग लागू किया गया है। इसे हमेशा उपयोग करने की अनुशंसा की जाती है।

List<String> arrayList = new ArrayList<String>(); 

क्योंकि यहां सूची संदर्भ लचीला है। यह LinkedList or Vector ऑब्जेक्ट भी रख सकता है।

6

अंतर यह है कि संस्करण 1 आपको ArrayList का उपयोग करने के लिए मजबूर करता है जबकि संस्करण 2 केवल गारंटी देता है कि List<String> लागू करता है।

बाद में आप इसे बिना किसी परेशानी के List<String> arrayList = new LinkedList<String>(); में बदल सकते हैं। संस्करण 1 के लिए आपको न केवल उस पंक्ति को बदलने की आवश्यकता हो सकती है बल्कि अन्य भागों को भी बदलना पड़ सकता है यदि वे ArrayList<String> के साथ काम करने पर भरोसा करते हैं।

इस प्रकार मैं लगभग किसी भी मामले में List<String> का उपयोग करेंगे, को छोड़कर जब मैं अतिरिक्त तरीकों कि ArrayList प्रदान करता है (जो कभी नहीं मामला था अब तक) कॉल करने के लिए आवश्यकता होगी: ensureCapacity(int) और trimToSize()

2

पहली घोषणा एक ऐरेलिस्ट होना चाहिए, दूसरा आसानी से किसी अन्य सूची प्रकार में बदला जा सकता है। इस प्रकार, दूसरे को प्राथमिकता दी जाती है क्योंकि यह स्पष्ट करता है कि आपको एक विशिष्ट कार्यान्वयन की आवश्यकता नहीं है। (कभी-कभी आपको वास्तव में एक कार्यान्वयन की आवश्यकता होती है, लेकिन यह दुर्लभ है)

+0

ठीक है, दूसरी तरफ पसंद नहीं किया जाता है जब गति फोकस होती है :- ''invokeinterface'' invokevirtual' से थोड़ा धीमा हो सकता है, जो कुछ संदर्भों में महत्वपूर्ण हो सकता है। – oldrinb

+1

यदि प्रदर्शन महत्वपूर्ण है तो मैं एक सरणी का उपयोग करूंगा। ;) –

1

ऐसी कुछ स्थितियां हैं जहां आप प्रदर्शन को बेहतर बनाने के लिए पहले (थोड़ा) बेहतर प्रदर्शन कर सकते हैं, उदाहरण के लिए कुछ JVMs without a JIT compiler पर।

उस तरह के बहुत विशिष्ट संदर्भ में से, आपको पहले का उपयोग करना चाहिए।

1

संभवत: आप इस लिंक http://docs.oracle.com/javase/6/docs/api/java/util/List.html

सूची का उल्लेख कर सकते एक interface.ArrayList, LinkedList आदि वर्ग है जो सूची को लागू कर रहे हैं।जब आप सूची इंटरफ़ेस का उपयोग कर रहे हैं, तो आपको ListIterator का उपयोग करके तत्वों को पुन: प्रारंभ करना होगा और सूची में आगे और पीछे स्थानांतरित कर सकते हैं, जहां Iterator का उपयोग करके ArrayList Iterate में और इसके तत्वों को एक-दूसरे के तरीके तक पहुंचा जा सकता है।

2

यह Set को List के कार्यान्वयन को बदलने के लिए आसान है:

Collection<String> stringList = new ArrayList<String>(); 
//Client side 
stringList = new LinkedList<String>(); 

stringList = new HashSet<String>(); 
//stringList = new HashSet<>(); java 1.7 and 1.8 
2

मूल रूप से यह जावा की अनुमति देता है वस्तुओं के कई प्रकार स्टोर करने के लिए एक संरचना कार्यान्वयन में, सामान्य प्रकार घोषणा (जैसे class MyStructure<T extends TT>) है, जो एक है द्वारा जावा मुख्य विशेषताएं।

ऑब्जेक्ट उन्मुख दृष्टिकोण मॉड्यूलरिटी और चिंताओं को अलग करके पुन: प्रयोज्यता में आधारित हैं - किसी भी प्रकार के ऑब्जेक्ट के साथ संरचना का उपयोग करने की क्षमता (जब तक यह कुछ नियमों का पालन करता है)।

आप सिर्फ बातें के रूप में पालन का दृष्टांत सकता है:

ArrayList list = new ArrayList(); 
बजाय

ArrayList<String> list = new ArrayList<>(); 

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

// this works 
List list1 = new ArrayList(); 
list1.add(1); 
list1.add("one"); 

// does not work 
List<String> list2 = new ArrayList<>(); 
list2.add(1); // compiler error here 
list2.add("one"); 

आप कुछ उदाहरण प्रलेखन documentation जाँच देखना चाहते हैं:

/** 
* Generic version of the Box class. 
* @param <T> the type of the value being boxed 
*/ 
public class Box<T> { 
    // T stands for "Type" 
    private T t; 

    public void set(T t) { this.t = t; } 
    public T get() { return t; } 
} 

तो फिर तुम जैसी चीजों का दृष्टांत सकता है:

class Paper { ... } 
class Tissue { ... } 

// ... 
Box<Paper> boxOfPaper = new Box<>(); 
boxOfPaper.set(new Paper(...)); 

Box<Tissue> boxOfTissues = new Box<>(); 
boxOfTissues.set(new Tissue(...)); 

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

Object l = new ArrayList<>(); का उपयोग कर के रूप में, आप तक पहुँचने नहीं कर रहे हैं List या ArrayList कार्यान्वयन ताकि आप संग्रह के साथ ज्यादा ऐसा करने में सक्षम नहीं होगा।

9

List एक इंटरफ़ेस है और ArrayList सूची इंटरफ़ेस का कार्यान्वयन है। सूची इंटरफेस में उपलब्ध विधियों के अलावा ArrayList कक्षा में केवल कुछ विधियां (i.e clone(), trimToSize(), removeRange() and ensureCapacity()) हैं। इसमें बहुत अंतर नहीं है।

1. List<String> l = new ArrayList<>(); 
    2. ArrayList<String> l = new ArrayList<>(); 

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

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

List<String> l = new ArrayList<>(); 
doSomething(l); 
प्रदर्शन की कमी के कारण

भविष्य में, यदि आप कार्यान्वयन LinkedList या someother वर्ग है जो List इंटरफ़ेस लागू करता है, बजाय ArrayList उपयोग करने के लिए बदल रहे हैं, तो आप एक बिंदु केवल (इन्स्टेन्शियशन हिस्सा) में बदलने की जरूरत है।

List<String> l = new LinkedList<>(); 

अन्यथा आप सभी स्थानों पर बदलना होगा, जहां भी, आपने विधि वर्ग के रूप में विशिष्ट वर्ग कार्यान्वयन का उपयोग किया है।

+0

क्या आप विस्तारित कर सकते हैं कि पहले विकल्प का उपयोग करने से हमें घोषणा रेखा से अधिक परिवर्तन करना पड़ता है? – TheLogicGuy

+0

लोग गूंगा प्रचार क्यों करते हैं "आप इसे बाद में बदल सकते हैं" तर्क? यदि आप इसे अच्छी तरह से डिज़ाइन करते हैं, तो इसे _always_ नियम के बजाय अपवाद होना चाहिए। यहां एकमात्र वास्तविक प्रभाव यह है कि आप 'सूची' मूलभूत बातें को छोड़कर अपने 'ऐरेलिस्ट' पर उपलब्ध सभी कार्यों को खो देते हैं। – Nyerguds

0

जब भी आप अमरूद की तरह खुले स्रोत समुदाय से और गूगल डेवलपर से कोडिंग देखा है (एंड्रॉयड लाइब्रेरी) वे इस दृष्टिकोण

List<String> strings = new ArrayList<String>(); 

इस्तेमाल किया है क्योंकि यह उपयोगकर्ता से कार्यान्वयन विस्तार को छिपाने के लिए है। प्रभावी जावा 2 संस्करण:: आइटम 52: आप ठीक

List<String> strings = new ArrayList<String>(); 

यह सामान्य दृष्टिकोण है और इस विशेष दृष्टिकोण

ArrayList<String> strings = new ArrayList<String>(); 

संदर्भ के लिए है