2010-07-13 5 views
16

जावा में "रेंज से बाहर" क्यों नहीं फेंक दिया गया है मैं जावा में substring() विधि का उपयोग कर रहा हूं और मुझे यकीन नहीं है कि यह "इंडेक्स से बाहर" त्रुटि क्यों नहीं फेंक रहा है।'substing (startIndex, endIndex)'

स्ट्रिंग abcde 0 से 4 सूचकांक शुरुआत है, लेकिन substring() विधि तथ्य यह है कि मैं फोन foo.substring (0) और प्राप्त "abcde" कर सकते हैं के आधार पर तर्कों के रूप STARTINDEX और ENDINDEX लेता है।

तो सबस्ट्रिंग (5) क्यों काम करता है? वह सूचकांक सीमा से बाहर होना चाहिए। स्पष्टीकरण क्या है?

/* 
1234 
abcde 
*/ 
String foo = "abcde"; 
System.out.println(foo.substring(0)); 
System.out.println(foo.substring(1)); 
System.out.println(foo.substring(2)); 
System.out.println(foo.substring(3)); 
System.out.println(foo.substring(4)); 
System.out.println(foo.substring(5)); 

इस कोड को आउटपुट:

abcde 
bcde 
cde 
de 
e 
    //foo.substring(5) output nothing here, isn't this out of range? 

जब मैं 5 6 के साथ बदलें:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: 
    String index out of range: -1 

उत्तर

18

Java API doc के अनुसार, सबस्ट्रिंग एक त्रुटि फेंकता है जब शुरू सूचकांक की तुलना में स्ट्रिंग की लंबाई अधिक है।

IndexOutOfBoundsException - if beginIndex is negative or larger than the length of this String object.

वास्तव में, वे एक उदाहरण बहुत आपके जैसे दे:

"emptiness".substring(9) returns "" (an empty string) 

मुझे लगता है कि इसका मतलब यह है कि यह सबसे अच्छा है निम्नलिखित है, जहां एक सूचकांक | में लपेटा जाता है के रूप में एक जावा स्ट्रिंग के बारे में सोच रहे हैं:

|0| A |1| B |2| C |3| D |4| E |5| 

एक स्ट्रिंग कहने के लिए एक प्रारंभ और अंत सूचकांक दोनों है।

+0

आह! टिप दोस्तों के लिए धन्यवाद, मैं एक ही दस्तावेज़ पृष्ठ पर देख रहा था लेकिन मुझे नहीं पता था कि मुझे अधिक जानकारी प्राप्त करने के लिए सभी तरह से नीचे स्क्रॉल करना पड़ा था ... –

+4

इच्छा है कि जावाडोक के बारे में कोई नोट हो, या मेरे जैसे लापरवाह लोग 'इंडेक्सऑटऑफबाउंड एक्सेप्शन' की उम्मीद है अगर शुरू होता है Index = String.length()। –

2

सबस्ट्रिंग (5) को अंक:

foo.substring(6) 

तो मैं त्रुटि मिलती है एक मौजूदा सूचकांक ... यह सिर्फ एक खाली इंगित होता है स्ट्रिंग। दूसरी ओर, substring (6), सिर्फ पागल बात है। :)

14

जब आप foo.substring(5) करते हैं, तो यह "ई" के बाद स्थिति में स्ट्रिंग शुरू होता है और स्ट्रिंग के अंत में समाप्त होता है। संयोग से, शुरुआत और अंत स्थिति समान होती है। इस प्रकार, खाली स्ट्रिंग। आप इंडेक्स को स्ट्रिंग में वास्तविक वर्ण नहीं मान सकते हैं, लेकिन वर्णों के बीच एक स्थिति है।

 --------------------- 
String: | a | b | c | d | e | 
     --------------------- 
Index: 0 1 2 3 4 5 
2

ऐसा इसलिए है क्योंकि सबस्ट्रिंग फ़ंक्शन एक "समावेशी" सबस्ट्रिंग देता है। तो स्ट्रिंग के अंत से पहले सूचकांक 5 बिंदुओं को इंगित करता है, लेकिन स्ट्रिंग के अंतिम प्रदर्शित चरित्र के बाद।

इस दस्तावेज में दिखाया गया है: http://download.oracle.com/docs/cd/E17476_01/javase/1.4.2/docs/api/java/lang/String.html#substring(int)

3

स्ट्रिंग एपीआई जावाडोक से:

public String substring(int beginIndex) 
    Returns a new string that is a substring of this 
    string. The substring begins with the "" character 
    at the specified index and extends to the end of this string. 

public String substring(int beginIndex, int endIndex) 
    Returns a new string that is a substring of this 
    string. The substring begins at the specified beginIndex 
    and extends to the character at index endIndex - 1. Thus 
    the length of the substring is endIndex-beginIndex. 

उदाहरण:

"unhappy".substring(2) returns "happy" 
"Harbison".substring(3) returns "bison" 
"emptiness".substring(9) returns "" (an empty string) 

"hamburger".substring(4, 8) returns "urge" 
"smiles".substring(1, 5) returns "mile" 

पैरामीटर:

beginIndex - the beginning index, inclusive. 
Returns: 
the specified substring. 
Throws: 
IndexOutOfBoundsException - if beginIndex is negative or 
larger than the length of this String object. 

====

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

3

मुझे पता है कि यह धागा काफी पुराना है लेकिन यह एक मौलिक समस्या है जो मुझे लगता है कि यह स्पष्टीकरण की गारंटी देता है।

प्रश्न ठीक से ठीक है। मैं जावा स्ट्रिंग.substring (int startIndex, int endIndex) विधि में सॉफ़्टवेयर गलती के रूप में इसे देखता हूं।

http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#substring%28int,%20int%29

जावा डॉक्स https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html

Java Arrays

जावा/C/C++ और हर दूसरे भाषा है कि मैं के बारे में पता सरणी तत्वों के बीच 'विभक्त' के रूप में सरणी सूचकांक देखने नहीं करता है।

पैरामीटर्स: startIndex - शुरुआत सूचकांक, समावेशी। एंड इंडेक्स - समापन सूचकांक, विशेष।

या तो एंड इंडेक्स का गलत नाम दिया गया है क्योंकि भाषा अंत में इंडेक्स + 1 पर पते तक स्मृति पहुंच की अनुमति नहीं देती है, जिसमें अंतिम सरणी तत्व शामिल करना आवश्यक है या एंड इंडेक्स गलत परिभाषित है और यह होना चाहिए: एंड इंडेक्स - समापन सूचकांक, समावेशी ।

सबसे संभावित मामला यह है कि दूसरा पैरामीटर गलत नाम दिया गया था। यह होना चाहिए: लंबाई - शुरुआत इंडेक्स से शुरू होने वाली स्ट्रिंग की लंबाई।

हम जानते हैं कि गोस्लिंग परिचितता के लिए सी/सी ++ भाषाओं पर जावा वाक्यविन्यास आधारित है। सी +++ स्ट्रिंग क्लास http://www.cplusplus.com/reference/string/string/substr/ से हम विधि परिभाषा देखते हैं:

स्ट्रिंग सबस्ट्र (size_t pos = 0, size_t len ​​= npos) const;

ध्यान दें कि विधि परिभाषा में दूसरा पैरामीटर लंबाई के लिए 'लेन' है।

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

टेस्टस्ट्रिंग में 10 वर्ण हैं, इंडेक्स पोजिशन 0 से 9 तक हैं। 10 का एंड इंडेक्स निर्दिष्ट करना हमेशा इंडेक्सऑटऑफबाउंड एक्सेप्शन() को फेंकना चाहिए क्योंकि टेस्टस्ट्रिंग का कोई अंत 10 नहीं है।

हम ठोस मूल्यों सी ++ विधि की ओर देखने वाले JUnit में विधि का परीक्षण करते हैं, तो हम उम्मीद करते हैं:

स्ट्रिंग testString = "testString"; assertThat (testString.substring (4, 6), बराबर ("स्ट्रिंग"));

लेकिन निश्चित रूप से हम अपेक्षित हो: "स्ट्रिंग" लेकिन था "सेंट"

सूचकांक 0 से testString की लंबाई 'स्ट्रिंग' में 'जी' चार के लिए 10 वर्ण है। यदि हम 10 को 'एंड इंडेक्स' पैरामीटर के रूप में उपयोग करते हैं,

स्ट्रिंग testString = "testString"; assertThat (testString.substring (4, 10), बराबर ("स्ट्रिंग"));

जुनीट से "पास"।

हम "lengthOfSubstringFromIndex0" करने के लिए पैरामीटर 2 का नाम बदलते हैं आप ENDINDEX करने के लिए की जरूरत नहीं है - 1 गिनती) जब एक ENDINDEX, 10 को निर्दिष्ट, और यह कभी IndexOutOfBoundsException (फेंकता है कि उम्मीद है, कि सीमा से बाहर के लिए है अंतर्निहित सरणी http://docs.oracle.com/javase/7/docs/api/java/lang/IndexOutOfBoundsException.html

यह केवल उन समयों में से एक है जिन्हें आपको इस विधि के idiosyncrasy को याद रखना होगा। दूसरा पैरामीटर सही ढंग से नामित नहीं है। जावा विधि हस्ताक्षर होना चाहिए:

public String substring(int beginIndex, 
      int lengthOfSubstringFromIndex0) 

या सी ++ स्ट्रिंग :: सबस्ट्र विधि से मेल खाने के लिए विधि को फिर से परिभाषित किया गया है। पाठ्यक्रम की परिभाषा का मतलब पूरे इंटरनेट को फिर से लिखना होगा, इसलिए इसकी संभावना नहीं है।

संबंधित मुद्दे