क्यों StringBuilder है जब वहाँ स्ट्रिंग है?


82

मैं सिर्फ StringBuilderपहली बार सामना किया था और आश्चर्यचकित था क्योंकि जावा में पहले से ही एक बहुत शक्तिशाली Stringवर्ग है जो लुभावना है।

एक दूसरी Stringकक्षा क्यों ?

मैं इसके बारे में और कहाँ जान सकता हूँ StringBuilder?



मैं सिर्फ यह नोट करना चाहता था कि यह वास्तव में एक बार मेरे लिए एक साक्षात्कार प्रश्न के रूप में आया था। उन्होंने पूछा कि मैं एक बड़े स्ट्रिंग को आबाद करने के लिए क्या करूंगा .....
पूर्वनिर्धारित करें

जवाबों:


171

Stringएप्लाइड की अनुमति नहीं देता है। प्रत्येक विधि जिसे आप Stringएक नई वस्तु बनाते हैं और उसे लौटाते हैं। ऐसा इसलिए है क्योंकि Stringयह अपरिवर्तनीय है - यह अपनी आंतरिक स्थिति को बदल नहीं सकता है।

दूसरी ओर StringBuilderपरस्पर परिवर्तनशील है। जब आप append(..)इसे कहते हैं तो एक नई स्ट्रिंग ऑब्जेक्ट बनाने के बजाय आंतरिक चार सरणी को बदल देता है।

इस प्रकार यह अधिक कुशल है:

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 500; i ++) {
    sb.append(i);
}

इसके बजाय str += i, जो 500 नए स्ट्रिंग ऑब्जेक्ट बनाएगा।

ध्यान दें कि उदाहरण में मैं एक लूप का उपयोग करता हूं। जैसा कि टिप्पणी में हेलिओस नोट करता है, संकलक स्वचालित रूप String d = a + b + cसे कुछ की तरह भावों का अनुवाद करता है

String d = new StringBuilder(a).append(b).append(c).toString();

ध्यान दें कि StringBufferइसके अतिरिक्त भी है StringBuilder। अंतर यह है कि पूर्व में सिंक्रनाइज़ किए गए तरीके हैं। यदि आप इसे स्थानीय चर के रूप में उपयोग करते हैं, तो उपयोग करें StringBuilder। यदि ऐसा होता है कि इसे कई थ्रेड्स द्वारा एक्सेस किया जाना संभव है, तो उपयोग करें StringBuffer(यह दुर्लभ है)


25
+1। आप जोड़ सकते हैं: "इसलिए StrungBuilder प्रदर्शन के लिए लग रहा है" और "Java स्ट्रिंगर A + B + C जैसे भावों को नए StringBuilder (A) .append (B) .append (C) .toString () जैसे ऑब्जेक्ट निर्माण प्रदर्शन से बचने के लिए प्रतिस्थापित करता है। दंड ":)
हेलिओस

और आप सभी को बहुत बहुत धन्यवाद। आप सभी 1 + के लायक हैं (जो तुरंत दिया जाएगा :)
a00b

'अपरिवर्तनीय' वस्तुओं के स्मरण जैसा सुपर।
गैरी त्सूई

शानदार प्रतिक्रियाएँ। हालांकि मुझे जो याद है, वह यही कारण है कि हम सिर्फ कंपाइलर का पता नहीं लगा सकते हैं, जब स्ट्रींगबिल्डर का उपयोग ज्यादातर समय करते हैं , जिसमें लूप शामिल हैं, ताकि आपको एक देव के रूप में इसके बारे में सोचने की आवश्यकता न हो। :)
दुनियाशी

अच्छा उत्तर । मैं इन पंक्तियों को जोड़ना चाहूंगा: स्ट्रिंग सरणी (यानी चार [मूल्य]) के रूप में अपरिवर्तनीय है जो स्ट्रिंग को अंतिम रूप से घोषित करता है लेकिन स्ट्रिंग स्ट्रिंग (यानी चार [मूल्य]) के मामले में जो स्ट्रिंग को पकड़ता है वह अंतिम नहीं है। आप स्ट्रिंग में परिवर्तन कर सकते हैं जो स्ट्रिंगर के मामले में स्ट्रिंग रखता है
दीन जॉन

61

यहाँ एक ठोस उदाहरण क्यों दिया गया है -

int total = 50000;
String s = ""; 
for (int i = 0; i < total; i++) { s += String.valueOf(i); } 
// 4828ms

StringBuilder sb = new StringBuilder(); 
for (int i = 0; i < total; i++) { sb.append(String.valueOf(i)); } 
// 4ms

जैसा कि आप देख सकते हैं कि प्रदर्शन में अंतर महत्वपूर्ण है।


Ps। मैंने अपने मैकबुक प्रो डुअल कोर पर इसे चलाया।
अमीर रामिनफर

25
यह समझाता है कि क्यों StringBuilder है जब वहाँ स्ट्रिंग है? यह स्पष्ट नहीं करता है कि स्ट्रिंगबर्ल इतनी तेज़ क्यों है। लेकिन यह सवाल नहीं है। तो यह एक मान्य उत्तर है।
केरेम बद्दोअन

2
@ क्रम्बी - सहमत। यह उत्तर देने के लिए कि वास्तव में दूसरे प्रश्न के लिए क्यों है।
अमीर रामिनफर

12
मुझे लगता है कि तुलना को उचित बनाने के लिए, आपको s = sb.ToString();अंत में प्रदर्शन करने का समय शामिल करना चाहिए ताकि कम से कम आपने दोनों उदाहरणों में एक ही किया हो (परिणाम एक है string)।
स्कॉट व्हिटलॉक

19

स्ट्रिंग क्लास अपरिवर्तनीय है, जबकि स्ट्रिंगबर्ल म्यूटेबल है।

String s = "Hello";
s = s + "World";

उपरोक्त कोड से दो ऑब्जेक्ट बनेंगे क्योंकि स्ट्रिंग अपरिवर्तनीय है

StringBuilder sb = new StringBuilder("Hello");
sb.append("World");

उपरोक्त कोड केवल एक ही वस्तु बनाएगा क्योंकि StringBuilder अपरिवर्तनीय नहीं है।

पाठ: जब भी स्ट्रिंग में हेरफेर करने / अपडेट करने / अपडेट करने की आवश्यकता होती है, तो स्ट्रिंग की तुलना में स्ट्रिंग को कई बार स्ट्रांगबर्ल के लिए जाना जाता है।


8

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


5

StringBuilder वर्ग म्यूट है और स्ट्रिंग के विपरीत, यह आपको स्ट्रिंग की सामग्री को संशोधित करने की आवश्यकता के बिना और अधिक स्ट्रिंग ऑब्जेक्ट्स बनाने की अनुमति देता है, जो कि जब आप किसी स्ट्रिंग को भारी रूप से संशोधित कर रहे हैं तो प्रदर्शन लाभ हो सकता है। StringBuilder नामक StringBuffer के लिए एक समकक्ष भी है जो कि सिंक्रनाइज़ भी है इसलिए यह बहुपरत वातावरणों के लिए आदर्श है।

स्ट्रिंग के साथ सबसे बड़ी समस्या यह है कि आप इसके साथ जो भी ऑपरेशन करते हैं, वह हमेशा एक नई वस्तु लौटाएगा, कहते हैं:

String s1 = "something";
String s2 = "else";
String s3 = s1 + s2; // this is creating a new object.

4

जब आप बड़े तार के साथ काम कर रहे हैं तो स्ट्रिंगबर्स्ट अच्छा है। यह आपको प्रदर्शन को बेहतर बनाने में मदद करता है।

यहाँ एक लेख है जो मैंने पाया कि मददगार था।

एक त्वरित Google खोज आपकी सहायता कर सकती थी। अब आपने अपने लिए एक Google खोज करने के लिए 7 अलग-अलग लोगों को काम पर रखा है। :)


क्या हम सभी यहाँ अवैतनिक कार्य नहीं कर रहे हैं?
सीए सेफ़

4

सटीक होने के लिए, स्ट्रिंग को जोड़ते हुए स्ट्रिंगबर्ल ओ (एन) है, जबकि स्ट्रिंग के ओ (एन ^ 2) को जोड़ते हुए। स्रोत कोड की जाँच करना, यह आंतरिक रूप से वर्णों के एक उत्परिवर्ती सरणी को रखकर प्राप्त किया जाता है। StringBuilder संभावित मेमोरी दोगुना करने की लागत पर, गोलाकार दोहराव तकनीक का उपयोग करके गोला बारूद O (N ^ 2) प्रदर्शन को प्राप्त करता है। आप इसे हल करने के लिए अंत में trimToSize कॉल कर सकते हैं, लेकिन आमतौर पर StringBuilder ऑब्जेक्ट केवल अस्थायी रूप से उपयोग किए जाते हैं। आप अंतिम स्ट्रिंग आकार में एक अच्छा शुरुआती अनुमान प्रदान करके प्रदर्शन में सुधार कर सकते हैं।


3

दक्षता।

हर बार जब आप तारों को समेटते हैं, तो एक नया स्ट्रिंग बनाया जाएगा। उदाहरण के लिए:

String out = "a" + "b" + "c";

यह एक नया, अस्थायी स्ट्रिंग बनाता है, "ए" में परिणाम के लिए इसमें "ए" और "बी" की प्रतिलिपि बनाता है। फिर यह एक और नया, अस्थायी स्ट्रिंग बनाता है, इसमें "abc" के परिणामस्वरूप "ab" और "c" कॉपी करता है। यह परिणाम तब सौंपा गया है out

परिणाम O (n () (द्विघात) समय जटिलता के पेंटर के एल्गोरिथ्म एक स्लेमियल है।

StringBuilderदूसरी ओर, आपको आउटपुट स्ट्रिंग को आवश्यक रूप से बदलते हुए, जगह में जोड़ देता है।


कई JVM कार्यान्वयन आपके उदाहरण को स्ट्रिंगबर्ल में संकलित करेंगे और फिर अंतिम परिणाम को स्ट्रिंग में बदल देंगे। ऐसे मामले में, इसे बार-बार स्ट्रिंग आवंटन द्वारा इकट्ठा नहीं किया जाएगा।
स्कॉटलैंड

1

जावा के पास स्ट्रिंग, स्ट्रिंगर और स्ट्रिंग है:

  • स्ट्रिंग: इसकी अपरिवर्तनीय

  • स्ट्रिंगरबफ़र: इसके म्यूटेबल और थ्रेडसेफ़

  • StringBuilder: इसके म्यूटेबल लेकिन नॉट थ्रेडसेफ़, जावा 1.5 में पेश किया गया

स्ट्रिंग उदाहरण:

public class T1 {

    public static void main(String[] args){

        String s = "Hello";

        for (int i=0;i<10;i++) {

            s = s+"a";
            System.out.println(s);
        }
    }
}

}

आउटपुट: सिर्फ 1 स्ट्रिंग के बजाय 10 अलग स्ट्रिंग्स बनाए जाएंगे।

Helloa
Helloaa
Helloaaa
Helloaaaa
Helloaaaaa
Helloaaaaaa
Helloaaaaaaa
Helloaaaaaaaa 
Helloaaaaaaaaa 
Helloaaaaaaaaaa

StringBuilder जैसे: केवल 1 StringBuilder ऑब्जेक्ट बनाया जाएगा।

public class T1 {

    public static void main(String[] args){

        StringBuilder s = new StringBuilder("Hello");

        for (int i=0;i<10;i++) {    
            s.append("a");
            System.out.println(s);
        }
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.