2010-05-05 28 views
37

कई जावा फ्रेमवर्क वर्ग Iterable लागू करते हैं, हालांकि String नहीं है। String में वर्णों पर पुनरावृत्ति करना समझ में आता है, जैसे कोई नियमित सरणी में आइटमों पर पुन: सक्रिय हो सकता है।जावा में स्ट्रिंग क्लास Iterable लागू क्यों नहीं करता है?

क्या कोई कारण है StringIterable लागू नहीं करता है?

+1

स्ट्रिंग के चार ऐरे के माध्यम से पुनरावृत्ति करने की समस्या को हल करता है? (strInput.ToCharArray) –

+4

टिम: स्ट्रिंग # toCharArray स्ट्रिंग के पात्रों की एक प्रति के साथ एक सरणी बनाता है। यहां तक ​​कि अगर यह काम करता है, तो यह पात्रों पर फिर से शुरू करने के लिए अनावश्यक ओवरहेड लगाता है। – jarnbjo

+1

@jambjo 'Iterator 'कम ओवरहेड होगा ??? –

उत्तर

17

वास्तव में कोई अच्छा जवाब नहीं है। जावा में एक पुनरावर्तक विशेष रूप से अलग वस्तुओं (वस्तुओं) के संग्रह पर लागू होता है। आपको लगता है कि String, जो CharSequence लागू करता है, अलग वर्णों का "संग्रह" होना चाहिए। इसके बजाए, इसे एक इकाई के रूप में माना जाता है जो वर्णों के साथ होता है।

जावा में, ऐसा लगता है कि इटरेटर केवल संग्रहों पर लागू होते हैं, न कि स्ट्रिंग के लिए। ऐसा कोई कारण नहीं है कि यह इस तरह क्यों है (जैसा कि मैं कह सकता हूं - आपको शायद गोस्लिंग या एपीआई लेखकों से बात करनी होगी); यह सम्मेलन या एक डिजाइन निर्णय प्रतीत होता है। दरअसल, CharSequenceIterable को लागू करने से कुछ भी नहीं है।

कहा कि, तुम इतनी तरह एक स्ट्रिंग में वर्णों से अधिक पुनरावृति कर सकते हैं:

for (int i = 0; i < str.length(); i++) { 
    System.out.println(str.charAt(i)); 
} 

या:

for(char c : str.toCharArray()) { 
    System.out.println(c); 
} 

या:

"Java 8".chars().forEach(System.out::println); 

भी ध्यान रखें कि आप संशोधित नहीं कर सकते जगह में एक स्ट्रिंग का एक चरित्र क्योंकि स्ट्रिंग्स अपरिवर्तनीय हैं। एक स्ट्रिंग के लिए परिवर्तनीय साथी स्ट्रिंगबिल्डर (या पुराना स्ट्रिंगबफर) है।

संपादित

इस जवाब पर टिप्पणी के आधार पर स्पष्ट करने के लिए। मैं को एक संभावित तर्क समझाऊंगा कि String पर कोई इटरेटर क्यों नहीं है। मैं यह कहने की कोशिश नहीं कर रहा हूं कि यह संभव नहीं है; वास्तव में मुझे लगता है कि यह CharSequence के लिए Iterable लागू करने के लिए समझ में आएगा।

StringCharSequence प्रदान करता है, जो केवल अवधारणात्मक रूप से String से अलग है। String आमतौर पर एक इकाई के रूप में सोचा जाता है, जबकि CharSequence बिल्कुल वैसा ही है: वर्णों का अनुक्रम। यह वर्णों के अनुक्रम पर एक इटरेटर (यानी, CharSequence पर) होने का अर्थ होगा, लेकिन केवल String पर ही नहीं।

रूप Foxfire ठीक ही टिप्पणी में बताया गया है, StringCharSequence इंटरफ़ेस लागू करता है, तो टाइप के लिहाज से, एक String एक CharSequence है। अर्थात्, मुझे लगता है कि वे दो अलग-अलग चीजें हैं - शायद मैं यहां पेडेंटिक हूं, लेकिन जब मैं String के बारे में सोचता हूं तो मैं आमतौर पर इसे एक इकाई के रूप में सोचता हूं जो वर्णों के साथ होता है। अंक 1, 2, 3, 4 और 1234 अंकों के अनुक्रम के बीच अंतर पर विचार करें। अब स्ट्रिंग abcd और वर्णों के अनुक्रम a, b, c, d के बीच अंतर पर विचार करें। मैं इस अंतर को इंगित करने की कोशिश कर रहा हूं।

मेरी राय में, पूछें कि क्यों String में एक इटरेटर नहीं है यह पूछने की तरह है कि Integer में एक इटरेटर क्यों नहीं है ताकि आप अलग-अलग अंकों पर फिर से सक्रिय हो सकें।

+4

निश्चित रूप से अक्षरों के संग्रह के रूप में एक स्ट्रिंग का इलाज पूरी तरह से बिना किसी उदाहरण के है, और इसे "समझ में आता है" मामले पर बहस करना थोड़ा गुस्सा – Svend

+0

@ यह सच है - मैं वास्तव में शब्दों के लिए एक नुकसान में था - मुझे लगता है कि मैं कहना चाहता था कि "कुछ मामलों में यह समझ में नहीं आता है" या यहां तक ​​कि "ज्यादातर मामलों में यह समझ में नहीं आता है" यह मानते हुए कि वास्तव में क्या हैं । मैं अपना जवाब संपादित करूंगा। –

+7

"ए स्ट्रिंग असतत वर्णों का वास्तव में" संग्रह "नहीं है।" यह ठीक है। वास्तव में यह CharSequence भी लागू करता है, जो बिल्कुल है: अलग वर्णों का एक आदेश संग्रह! – Foxfire

1

तुम सच में यहाँ पुनरावृत्ति में instrested रहे हैं:

String str = "StackOverflow"; 

for (char c: str.toCharArray()){ 
    //here you go 
} 
+2

-1 क्षमा करें, लेकिन मुझे नहीं पता कि इस सवाल के सवाल के साथ क्या जवाब देना है। – jarnbjo

+3

एक समस्या यह हो सकती है किCharArray एक नई सरणी बनाता है। तो यह बहुत अक्षम है। – Foxfire

+0

@ हेल्पर: स्ट्रिंग अपरिवर्तनीय है। हालांकि लौटा ऐरे नहीं है। और Array changinig स्ट्रिंग को प्रभावित नहीं करना चाहिए। तो यह एक पूरी प्रतिलिपि बनाता है। – Foxfire

12

वजह साफ है: स्ट्रिंग वर्ग Iterable की तुलना में काफी पुराना है।

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

हालांकि यह कुछ हद तक अपूर्ण है क्योंकि Iterable ऑब्जेक्ट देता है। तो इसे हर चार लौटाना होगा।

संपादित करें: जैसा कि तुलना: .Net स्ट्रिंग पर गणना करने का समर्थन करता है, हालांकि .Net Iterable देशी प्रकारों पर भी काम करता है, इसलिए जावा में इसकी आवश्यकता होने पर कोई रैपिंग आवश्यक नहीं है।

+0

"स्ट्रिंग क्लास के लिए इटरटेबल जोड़ना यह अनिवार्य बनाता है", समझ में आता है; लेकिन किसी ने स्ट्रिंग क्लास को इट्रेबल नहीं जोड़ा क्योंकि यह पुराना था, थोड़ा अजीब लगता है।क्या आप कुछ और बता सकते हैं? – phoenix24

+0

स्ट्रिंग Iterable से पहले लंबे समय से अस्तित्व में था। तो आपको बाद में इंटरफ़ेस जोड़ना होगा। हालांकि यह संभव है - कुछ कोने के मामलों में - एक तोड़ने वाला परिवर्तन हो सकता है। और यह ध्यान में रखते हुए कि स्ट्रिंग का कितनी बार उपयोग किया जाता है * शायद * कुछ जोखिम भरा माना जा सकता है। यह सिर्फ अनुमान लगा रहा है। मुझे कोई ज्ञान नहीं है अगर ये विचार वास्तव में उस निर्णय को प्रभावित कर रहे थे। लेकिन ऐसा लगता है कि सबसे अधिक संभावना है। – Foxfire

+1

मैं 'स्ट्रिंग' को' ब्रेकिंग चेंज 'के रूप में' Iterable' (या किसी भी प्रकार) को जोड़ने में नहीं देख सकता। ऐसा नहीं है कि आप 'स्ट्रिंग' (भगवान का शुक्रिया) उपclass कर सकते हैं। –

0

Iterable क्या? Iterable<Integer> अधिकतर समझ में आएगा, जहां प्रत्येक तत्व यूनिकोड कोडपॉइंट का प्रतिनिधित्व करता है। Iterable<Character> धीमा और व्यर्थ होगा जब हमारे पास toCharArray होगा।

10

क्या इसके लायक है के लिए, मेरे सहकर्मी जोश बलोच दृढ़ता से जावा 7 के लिए इस सुविधा को जोड़ने के लिए चाहता है:

for (char c : aString) { ... }

और

for (int codePoint : aString) { ... }

इस पाश के लिए सबसे आसान तरीका क्या होगा वर्णों और तार्किक पात्रों (कोड अंक) पर कभी भी। StringIterable को लागू करने की आवश्यकता नहीं होगी, जो मुक्केबाजी को होने के लिए मजबूर करेगा।

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

+5

आप जोशुआ ब्लोच के साथ काम करते हैं? मिठाई! –

+0

बहुत बुरा है जिसने इसे जावा 7 के प्रोजेक्ट सिक्का में नहीं बनाया है। – akuhn

+0

यदि उन्हें किसी दिन ऐसा करने की योजना बनाई गई थी, तो सुनिश्चित करें कि यह किसी भी ऑब्जेक्ट के लिए काम करता है, केवल 'स्ट्रिंग' के लिए लागू किए गए 'CharSequence' को प्राप्त करता है। –

4

वे बस ऐसा करने के लिए भूल गए।

+0

क्या आपके पास इस दावे के लिए कोई सबूत है? ऐसा लगता है कि ऐसा लगता है कि ऐसा इसलिए है क्योंकि स्ट्रिंग इटरेबल इंटरफ़ेस (स्ट्रिंग्स की अनुमानित तारीख जावा 1.0 पर वापस आती है, आईटेबल की तारीख जावा 1.5 पर वापस आती है), और एक बार जब भाषा विनिर्देशक स्ट्रिंग को संग्रह में से एक के रूप में नहीं मानते थे, उन्होंने इस तरह से इलाज जारी रखा। – Anomaly

2

स्ट्रिंग कार्यान्वयन Iterable बनाने के मुख्य कारणों में से एक है ऊपर वर्णित अनुसार (प्रत्येक) लूप के लिए सरल सक्षम करना है। इसलिए, स्ट्रिंग कार्यान्वयन Iterable को लागू करने का एक कारण एक भयानक कार्यान्वयन की अंतर्निहित अक्षमता हो सकता है, क्योंकि इसके परिणामस्वरूप मुक्केबाजी की आवश्यकता होती है। हालांकि, अगर परिणामी इटरेटर (जैसा कि स्ट्रिंग.इटरेटर() द्वारा लौटाया गया है) का कार्यान्वयन अंतिम है, तो कंपाइलर विशेष-केस कर सकता है और मुक्केबाजी/अनबॉक्सिंग से बाइट-कोड मुक्त कर सकता है।

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