मुझे आकार की जांच या सीमा से बाहर जाने के बिना एक स्ट्रिंग के पहले एन अक्षर कैसे मिलते हैं?


163

मैं nजावा में एक स्ट्रिंग के पहले अक्षर तक कैसे जा सकता हूं बिना आकार की जांच किए पहले (इनलाइन स्वीकार्य है) या ए का जोखिम IndexOutOfBoundsException?


1
जब तक आप अपवाद नहीं पकड़ते, मुझे नहीं पता कि आप उस मामले को संभालने की योजना कैसे बनाते हैं जहां चरित्र की लंबाई स्ट्रिंग की लंबाई से अधिक है।
मैट बोहम

2
क्यों? लंबाई की जाँच करने या अपवाद को पकड़ने में आपका क्या विरोध है?
पैक्सिडाब्लो

1
जिज्ञासा के बहुत से, आप आकार की जांच से क्यों बचना चाहते हैं। यह सी। नहीं है
टॉम हॉन्टिन -

मैं व्यक्त करने के लिए क्या करना चाहता था, अगर एक / नहीं तो ब्लॉक से बचने की इच्छा थी, वास्तव में लंबाई की जांच करने के लिए नहीं।
एंटनी.ट्रूप

संभावित डुप्लिकेट: stackoverflow.com/questions/8499698/…
मुल्की

जवाबों:


347

यहाँ एक साफ समाधान है:

String upToNCharacters = s.substring(0, Math.min(s.length(), n));

राय: जबकि इस समाधान "साफ" है, मुझे लगता है कि यह वास्तव में है कम पठनीय एक समाधान की तुलना में है कि का उपयोग करता है if/ elseस्पष्ट तरीके से। यदि पाठक ने इस चाल को नहीं देखा है, तो उसे कोड को समझने के लिए कठिन सोचना होगा । IMO, कोड का अर्थ if/ elseसंस्करण में अधिक स्पष्ट है । एक क्लीनर / अधिक पठनीय समाधान के लिए, @ paxdiablo का उत्तर देखें।


1
+1। इससे भी बेहतर अगर यह एक फ़ंक्शन में लपेटा जाता है जिसका नाम safe_substring या substring_safe है, जैसे कि paxdiablo का उत्तर, ताकि उपयोग पढ़ने में आसान हो / अधिक स्पष्ट हो।
टूलमेकरसैट

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

88

पहिया को सुदृढ़ न करें ...:

org.apache.commons.lang.StringUtils.substring(String s, int start, int len)

जावदोक कहते हैं:

StringUtils.substring(null, *, *)    = null
StringUtils.substring("", * ,  *)    = "";
StringUtils.substring("abc", 0, 2)   = "ab"
StringUtils.substring("abc", 2, 0)   = ""
StringUtils.substring("abc", 2, 4)   = "c"
StringUtils.substring("abc", 4, 6)   = ""
StringUtils.substring("abc", 2, 2)   = ""
StringUtils.substring("abc", -2, -1) = "b"
StringUtils.substring("abc", -4, 2)  = "ab"

इस प्रकार:

StringUtils.substring("abc", 0, 4) = "abc"

1
यह सवाल का जवाब नहीं देता है, लेकिन इसकी परवाह किए बिना यह अभी भी समाधान प्रदान करता है। अगर ओपी समझने में सक्षम है, तो मुझे लगता है कि यह एक बेहतर समाधान है।
अउल्लाह

5
यह इंगित करने के लिए भी उपयोगी हो सकता है कि StringUtils.substring(yourString, 0, n)जैसा है वैसा नहीं है yourString.substring(0, n)। पूर्व से है StringUtils, जबकि बाद का उपयोग कर रहा है String.substring(जो अपवाद देता है यदि अंत सूचकांक स्ट्रिंग की लंबाई से अधिक है)।
टूलमेकरस्टेव

FYI के रूप में यदि आप इस विधि के लिए स्रोत में देखते हैं तो इसकी स्थिति उस मामले को संभालती है जहां अंत लंबाई को लंबाई बदलकर लंबाई से अधिक है:if (end > str.length()) { end = str.length();}
bholl

1
का अंतिम पैरामीटर StringUtils.substring(String s, int start, int len)लेन नहीं है, यह एंड-इंडेक्स है।
गोरोदे

StringUtils.substring ("एबीसी", 0, 4) = "एबीसी", मेरे लिए काम किया। धन्यवाद !
आकाश 5288

42

अपाचे कॉमन्स लैंग के पास इसके लिए एक StringUtils.leftतरीका है।

String upToNCharacters = StringUtils.left(s, n);

यह सबसे अच्छा समाधान नहीं होना चाहिए? क्यों नहीं कई इस मतदान कर रहे हैं?
डू

3
हो सकता है क्योंकि अन्य लोगों के पास आपकी जैसी राय नहीं है? :-)
स्टीफन सी।

यह उत्तर मूल प्रश्न पूछने की तारीख से बहुत बाद में आया।
मुल्की

@DoWill: क्योंकि आपके निष्पादन योग्य वातावरण में एक (अन्य) 3-पार्टी लाइब्रेरी जोड़ना हमेशा सार्थक नहीं होता है।
लार्स

12

एसओ पर सवाल का एक वर्ग है जो कभी-कभी पूर्ण अर्थ से कम बनाता है, यह एक खतरनाक रूप से करीब है :-)

शायद आप अपने दो तरीकों में से एक का उपयोग करके अपने फैलाव की व्याख्या कर सकते हैं।

यदि यह सिर्फ इसलिए है क्योंकि आप अपने कोड को ifस्टेटमेंट या अपवाद को पकड़ने वाले कोड से काली मिर्च नहीं डालना चाहते हैं , तो एक समाधान एक सहायक फ़ंक्शन का उपयोग करना है जो आपके लिए इसका ध्यान रखेगा, कुछ इस तरह:

static String substring_safe (String s, int start, int len) { ... }

जो पहले से लंबाई की जाँच करेगा और उसके अनुसार कार्य करेगा (या तो छोटे स्ट्रिंग या पैड को रिक्त स्थान के साथ लौटाएगा)।

फिर आपको अपने कोड में इसके बारे में चिंता करने की ज़रूरत नहीं है, बस कॉल करें:

String s2 = substring_safe (s, 10, 7);

के बजाय:

String s2 = s.substring (10,7);

यह उस मामले में काम करेगा जो आपको चिंतित करने वाला लगता है (अन्य उत्तरों के लिए आपकी टिप्पणियों के आधार पर), बहुत सारे स्ट्रिंग बिल्डिंग सामान करते समय कोड के प्रवाह को नहीं तोड़ना।


1
आपको टिप्पणी को अधिक बारीकी से पढ़ना चाहिए, @antony, विशेष रूप से स्माइली, और मदद करने की कोशिश करने वालों के बारे में इतना कीमती नहीं होना चाहिए। मैं केवल यह कह रहा था कि आपने दो तरीकों से बचने के लिए कोई तर्क नहीं दिया था। और यह एक वास्तविक उत्तर है, एक सहायक फ़ंक्शन का उपयोग करते हुए, यही कारण है कि यह एक टिप्पणी में नहीं है।
paxdiablo

1
+1: यह स्वीकार किए जाते हैं कि ओपी कोड को अव्यवस्थित नहीं करने की इच्छा से बेहतर दृष्टिकोण है। (या एक पुस्तकालय है कि पहले से ही वांछित के रूप में व्यवहार करता है शामिल है एक पुस्तकालय के Nickkk समाधान देखें।)
ToolmakerSteve

12
String upToNCharacters = String.format("%."+ n +"s", str);

अगर nएक चर है (तो आपको प्रारूप स्ट्रिंग का निर्माण करना चाहिए)

String upToNCharacters = String.format("%.10s", str);

डॉक्स


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

सर्वश्रेष्ठ उत्तर क्योंकि इनपुट स्ट्रिंग केवल एक बार पढ़ा जाता है, इसलिए इसे चर में संग्रहीत करने की आवश्यकता नहीं है, जो इसे बड़े करीने से एम्बेड करना संभव बनाता है।
Profiterole

3

प्रतिस्थापन विधि का उपयोग करें, इस प्रकार है:

int n = 8;
String s = "Hello, World!";
System.out.println(s.substring(0,n);

यदि n स्ट्रिंग की लंबाई से अधिक है, तो यह एक अपवाद को फेंक देगा, जैसा कि एक टिप्पणीकार ने बताया है। एक सरल उपाय यह है कि इस स्थिति if(s.length()<n)को अपने elseखंड में लपेटें , आप यह चुन सकते हैं कि क्या आप पूरे स्ट्रिंग को प्रिंट / वापस करना चाहते हैं या इसे दूसरे तरीके से संभालना चाहते हैं।


1
इस जोखिम को एक इंडेक्सऑउटऑफबाउंडएक्ससेप्शन मिल रहा है
antony.trupe

वैसे, यदि आप जावा में प्रोग्रामिंग पर योजना बनाते हैं, तो आपको स्ट्रिंग ( java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html ) के लिए अधिकांश API विधियों को याद करने का प्रयास करना चाहिए ।
मैट बोहम

मैंने पहले ही सबस्टेशन को खारिज कर दिया है, कम से कम अपने आप से, उत्तर के रूप में नहीं
एंटनी.ट्रूप

आपको या तो आकार की जांच करनी होगी या अपवाद को पकड़ना होगा। क्या मैं पूछ सकता हूं कि इनमें से कोई भी करना आपकी स्थिति में काम नहीं करेगा?
मैट बोहम

3
यह सवाल का जवाब कैसे है? सवाल पूछ रहा था कि पहले साइज चेक कैसे नहीं करना है, न ही अपवाद का कारण बनना चाहिए।
टूलमेकरस्टेव

3

यदि आप कोटलिन के साथ विकसित करने के लिए पर्याप्त भाग्यशाली हैं,
तो आप takeअपने लक्ष्य को प्राप्त करने के लिए उपयोग कर सकते हैं ।

val someString = "hello"

someString.take(10) // result is "hello"
someString.take(4) // result is "hell" )))

0

ApacheCommons ने मुझे आश्चर्यचकित किया, StringUtils.abbreviate(String str, int maxWidth)"..." पोस्टफ़िक्स को बदलने का कोई विकल्प नहीं है। WordUtils.abbreviate(String str, int lower, int upper, String appendToEnd)अगले खाली स्थान तक दिखता है।

मैं इसे यहाँ छोड़ने जा रहा हूँ:

public static String abbreviate(String s, int maxLength, String appendToEnd) {
    String result = s;
    appendToEnd = appendToEnd == null ? "" : appendToEnd;
    if (maxLength >= appendToEnd.length()) {
        if (s.length()>maxLength) {
            result = s.substring(0, Math.min(s.length(), maxLength - appendToEnd.length())) + appendToEnd;
        }
    } else {
        throw new StringIndexOutOfBoundsException("maxLength can not be smaller than appendToEnd parameter length.");
    }
    return result;
}

1
@ VolkanGüven इसकी वजह से "ApacheCommons ने मुझे हैरान कर दिया" वाक्य। मैं पवित्र ApacheCommons पुस्तकालय critisizing के माध्यम से पाप की सराहना की। या जो भी हो ...
yuceel

0

कोटलिन: (अगर किसी को ज़रूरत हो)

var mText = text.substring(0, text.length.coerceAtMost(20))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.