सरणी की लंबाई संपत्ति को कहां परिभाषित किया गया है?


263

हम ArrayList<E>इसकी सार्वजनिक विधि का उपयोग करके लंबाई निर्धारित कर सकते हैं size(), जैसे

ArrayList<Integer> arr = new ArrayList(10);
int size = arr.size();

इसी प्रकार हम संपत्ति Arrayका उपयोग करके किसी वस्तु की लंबाई निर्धारित कर सकते lengthहैं

String[] str = new String[10];
int size =  str.length;

जबकि कक्षा के अंदर की size()विधि ArrayListको परिभाषित किया गया है ArrayList, यह परिभाषित की गई lengthसंपत्ति कहां है Array?


प्रश्न संगठन के संदर्भ में, मैं आपके प्रश्न को रखने का सुझाव दूंगा "एरे की लंबाई संपत्ति को कहां परिभाषित किया गया है?" अपने पोस्ट को शुरुआती ट्यूटोरियल की तरह लगने से रोकने के लिए सभी स्पष्टीकरणों से पहले।
NoName

जवाबों:


250

एर जावा में विशेष वस्तुएं हैं, उनके पास एक सरल विशेषता है जिसका नाम lengthहै final

किसी सरणी की कोई "वर्ग परिभाषा" नहीं है (आप इसे किसी भी .class फ़ाइल में नहीं पा सकते हैं), वे स्वयं भाषा का हिस्सा हैं।

10.7। अर्रे सदस्य

एक सरणी प्रकार के सदस्य निम्नलिखित हैं:

  • public finalक्षेत्र lengthहै, जो सरणी के घटकों की संख्या में शामिल है। lengthसकारात्मक या शून्य हो सकता है।
  • publicविधि cloneहै, जो कक्षा में एक ही नाम के विधि को ओवरराइड करता है Objectऔर फेंकता है कोई अपवाद नहीं की जाँच की। cloneसरणी प्रकार की विधि का रिटर्न प्रकार T[]है T[]

    एक बहुआयामी सरणी का एक क्लोन उथला है, जो कहना है कि यह केवल एक नया सरणी बनाता है। सबरेज़ साझा किए जाते हैं

  • सभी सदस्य वर्ग से विरासत में मिले Object; Objectविरासत में मिली एकमात्र विधि इसकी cloneविधि नहीं है।

संसाधन:


84
ध्यान दें कि ArrayList.size()वास्तव में सरणी में संग्रहीत ऑब्जेक्ट की संख्या प्रदान करता है जबकि myArray.length( []) "क्षमता" प्रदान करता है। यही है, अगर के लिए myArray = new int[10];, यह 10 लौटाता है। यह उन वस्तुओं की संख्या नहीं है जिन्हें आपने सरणी में रखा है।
wmorrison365

1
@Colin कैसे सरणी वस्तुएं इतनी विशेष हैं मेरा मतलब है कि डिजाइनरों को इसे विशेष बनाने की आवश्यकता क्यों है और किसी सरणी की वर्ग फ़ाइल क्यों नहीं प्रदान करना है?
विकास वर्मा

5
@VikasVerma एरे वस्तुओं की तरह क्यों नहीं हैं? इतिहास की वजह से। जब जावा को डिज़ाइन किया गया था, तो सिंटैक्स और शैली में C के समान नहीं होने पर भाषा नवाचार में अधिकांश प्रयास विफल रहे। इस प्रकार सी ++, ऑब्जेक्टिव-सी और जावा उस युग के दौरान अस्पष्टता से बचने के लिए कुछ भाषाओं में से थे। जावा को सचेत रूप से दिन के मुख्यधारा के प्रोग्रामर से परिचित होने के लिए घुंघराले ब्रेसिज़, प्राइमेटिक्स और सादे सरणियों को शामिल करने के लिए डिज़ाइन किया गया था । जेम्स गोस्लिंग और अन्य सन लोगों के साथ साक्षात्कार देखें। कुछ लोग शुद्ध OOP के लिए संग्रह के साथ चिपके रहते हैं, और सादे सरणियों से बचते हैं।
बासिल बॉर्क

1
@VikasVerma, कुछ बिंदु पर, निचले स्तर की तकनीक पर जावा का निर्माण किया जाना चाहिए। यदि जावा मौजूद नहीं है, तो आप इसे जावा के साथ नहीं बना सकते। आपको अपने अस्तित्व के लिए संदर्भ रखने के लिए बाकी जावा के लिए कुछ आदिम संकलन बनाने के लिए सी ++ (या कुछ और, लेकिन इस मामले में सी ++) का उपयोग करना होगा। अंत में रॉक सीएल में जहां आप इसे C ++ में कोड करते हैं, उसके बिना आपके पास सब कुछ के लिए कक्षाएं नहीं हो सकती हैं। आप जावा में एक सरणी का निर्माण कैसे करेंगे? यदि आप Listउनके कार्यान्वयन में सरणियों का उपयोग करने वाले कारण का उपयोग नहीं कर सकते हैं ।
अलेक्जेंडर बर्ड

आप इसे जवाब देने के लिए चाहते हैं, तो के रूप में है , तो stackoverflow.com/a/50506451/1059372
यूजीन

114

यह मूल रूप से "विशेष" है, अपने स्वयं के बाइटकोड निर्देश के साथ arraylength:। तो यह विधि:

public static void main(String[] args) {
    int x = args.length;
}

इस तरह से बाइटकोड में संकलित किया जाता है:

public static void main(java.lang.String[]);
  Code:
   0:   aload_0
   1:   arraylength
   2:   istore_1
   3:   return

इसलिए इसे एक्सेस नहीं किया जाता क्योंकि यह एक सामान्य क्षेत्र था। वास्तव में, यदि आप इसे पाने की कोशिश करते हैं जैसे कि यह एक सामान्य क्षेत्र था, इस तरह, यह विफल रहता है:

// Fails...
Field field = args.getClass().getField("length");
System.out.println(field.get(args));

इसलिए दुर्भाग्य से, सार्वजनिक अंतिम फ़ील्ड वाले प्रत्येक सरणी प्रकार के JLS विवरण lengthकुछ भ्रामक हैं :(


1
मुझे अल्बर्ट आइंस्टीन का एक उद्धरण ठीक से याद नहीं है लेकिन यह कहते हैं कि "लोगों को एक बात बहुत अच्छी तरह से समझ में आती है केवल चीजों को बहुत सरल तरीके से समझा सकते हैं" मुझे लगता है कि यह आपको बहुत अच्छी लगती है :)
जावा

@ जीन स्कीट कैसे सरणी वस्तु विशेष है मेरा मतलब है कि डिजाइनरों को इसे विशेष बनाने की आवश्यकता क्यों है और एक सरणी की वर्ग फ़ाइल क्यों नहीं प्रदान करना है?
विकास वर्मा

2
@VikasVerma: किसी सरणी ऑब्जेक्ट के आकार के बारे में सोचें। अन्य सभी प्रकारों का एक निश्चित आकार होता है - प्रत्येक आवृत्ति समान आकार की होती है, जबकि सरणियाँ उनकी लंबाई के आधार पर भिन्न होती हैं। वह सिर्फ एक उदाहरण है। यदि आपको लगता है कि आप कुछ विशेष का उपयोग किए बिना एक ही परिणाम प्राप्त कर सकते हैं, तो आपको क्या लगता है कि एक सरणी वर्ग के क्षेत्र कैसे दिखेंगे? int[]जब आप जेनरिक आदिम प्रकारों पर लागू नहीं होते हैं तो आप कैसे प्रतिनिधित्व करेंगे ? (और बिल्ली, जेनेरिक वैसे भी लंबे समय तक मौजूद नहीं था।) आप सभी संग्रह के लिए लिंक की गई सूचियों का उपयोग करके बिना सरणियों से दूर हो सकते हैं, लेकिन यह दक्षता के लिए भयानक होगा।
जॉन स्कीट

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

@VikasVerma: StringBufferवर्ग खुद करता है, हाँ - क्योंकि यह एक संदर्भ रखता है char[](या किया, कम से कम; मुझे नहीं पता कि यह अभी भी करता है, ऑफ-हैंड)। इसलिए जब कोई StringBuilderअधिक मेमोरी के लिए जिम्मेदार होता है, तो उसका तत्काल आकार और लेआउट तय हो जाता है।
जॉन स्कीट

18

यह जावा भाषा विनिर्देश में परिभाषित है :

एक सरणी प्रकार के सदस्य निम्नलिखित हैं:

  • public finalक्षेत्र lengthहै, जो सरणी के घटकों की संख्या में शामिल है। lengthसकारात्मक या शून्य हो सकता है।

चूंकि सरणी प्रकारों की एक सीमित संख्या है (प्रत्येक वर्ग के लिए एक समान सरणी प्रकार है, और फिर बहुआयामी सरणियाँ हैं), उन्हें एक वर्ग फ़ाइल में लागू नहीं किया जा सकता है; जेवीएम को इसे उड़ान पर करना होगा।


15

भले ही यह सवाल का सीधा जवाब नहीं है, यह .lengthबनाम .size()तर्क के लिए एक अतिरिक्त है । मैं इस प्रश्न से संबंधित कुछ शोध कर रहा था, इसलिए जब मैं इसके पार आया तो मैंने देखा कि यहाँ परिभाषा (ओं) को प्रदान किया गया है

सार्वजनिक अंतिम फ़ील्ड लंबाई, जिसमें सरणी के घटकों की संख्या होती है

"बिल्कुल" सही नहीं है।

फ़ील्ड की लंबाई में घटक डालने के लिए उपलब्ध स्थानों की संख्या होती है , न कि सरणी में मौजूद घटकों की संख्या। तो यह उस सरणी के लिए आवंटित कुल उपलब्ध मेमोरी का प्रतिनिधित्व करता है, न कि उस मेमोरी का कितना भरा हुआ है।

मेमोरी आवंटन आवंटित करें

उदाहरण:

static class StuffClass {
    int stuff;
    StuffClass(int stuff) {
        this.stuff = stuff;
    }
}

public static void main(String[] args) {

    int[] test = new int[5];
    test[0] = 2;
    test[1] = 33;
    System.out.println("Length of int[]:\t" + test.length);

    String[] test2 = new String[5];
    test2[0] = "2";
    test2[1] = "33";    
    System.out.println("Length of String[]:\t" + test2.length);

    StuffClass[] test3 = new StuffClass[5];
    test3[0] = new StuffClass(2);
    test3[1] = new StuffClass(33);
    System.out.println("Length of StuffClass[]:\t" + test3.length);         
}

आउटपुट:

Length of int[]:        5
Length of String[]:     5
Length of StuffClass[]: 5

हालाँकि, की .size()संपत्ति ArrayListसूची में तत्वों की संख्या देती है:

ArrayList<Integer> intsList = new ArrayList<Integer>();
System.out.println("List size:\t" + intsList.size());
intsList.add(2);
System.out.println("List size:\t" + intsList.size());
intsList.add(33);
System.out.println("List size:\t" + intsList.size());

आउटपुट:

List size:  0
List size:  1
List size:  2

1
यह सही है, क्योंकि सभी तत्व शून्य से आरंभिक हैं। Arrays "खाली" नहीं हो सकता
Guido

ठीक है कि मैं क्या कहा है। यह "बिल्कुल" सही नहीं है। यह अभी भी 5 की लंबाई है, भले ही सरणी में कुछ भी नहीं जोड़ा गया हो। इस प्रकार यह सरणी में तत्वों की संख्या को "बिल्कुल" नहीं रखता है। आपकी टिप्पणी मेरे जवाब के लिए सिर्फ एक अतिरिक्त है, इसे गलत बनाने का कारण नहीं है।
nem035

यदि आप nullगैर-अशक्त तत्वों के बीच अंतर करने की कोशिश करते हैं तो यह "गलत" हो सकता है । लेकिन भेद काम नहीं करता है। सब के बाद, size()(कहते हैं) Listमें nullमान भी शामिल हो सकते हैं ।
स्टीफन सी

हाँ, मूल रूप से मेरी बात यह थी कि sizeगतिशील रूप से व्यवहार करता है, जबकि lengthएक स्थिर संपत्ति है ... तथ्य यह है कि एक सरणी में शेष अपूर्ण स्थान " नॉन वैल्यूज़ " (प्रकार के आधार पर) को प्रारंभिक रूप से इस बिंदु का विरोध नहीं करता है।
nem035

5

यह सार्वजनिक अंतिम फ़ील्ड है, जिसमें सरणी के घटकों की संख्या शामिल है (लंबाई सकारात्मक या शून्य हो सकती है)

इस प्रकार एक सरणी में निम्न वर्ग के समान सार्वजनिक क्षेत्र और विधियाँ हैं:

class A implements Cloneable, java.io.Serializable {
    public final int length = X;
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            throw new InternalError(e.getMessage());
        }
    }
}

अधिक जानकारी पर

10.7 सरणी सदस्य

http://java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html


0

इसका उत्तर देने के लिए यह है कि, सरणी की यह लंबाई संपत्ति कहाँ परिभाषित की गई है ? एक विशेष में Object header

जोल के माध्यम से देखने में आसान

 int [] ints = new int[23];
 System.out.println(ClassLayout.parseInstance(ints).toPrintable());

इस आउटपुट में से एक लाइन यह होने जा रही है:

OFFSET  SIZE      TYPE DESCRIPTION
16       4        (object header)   17 00 00 00 (00010111 00000000 00000000 00000000) (23)

आमतौर पर वस्तुओं दो हेडर (मार्क और klass), सरणियों एक और है कि हमेशा पर कब्जा है है 4 bytesलंबाई में, के रूप में sizeएक है int


-1

कीवर्ड की लंबाई परिभाषित फाइल किए गए डेटा की तरह काम करती है। किसी ऐरे में उपयोग करते समय, हम ऐरे में कितने तत्वों को एक्सेस करने के लिए इसका उपयोग कर सकते हैं। स्ट्रिंग [] के बारे में, हम स्ट्रिंग वर्ग में परिभाषित लंबाई () विधि को लागू कर सकते हैं। ArrayList के संबंध में, हम ArrayList में परिभाषित आकार () विधि का उपयोग कर सकते हैं। ध्यान दें कि ArrayList <> (क्षमता) के साथ एक सरणी सूची बनाते समय, इस सरणी सूची का प्रारंभिक आकार () शून्य है क्योंकि कोई तत्व नहीं है।

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