जावा में स्ट्रिंग्स की अपरिवर्तनीयता


218

निम्नलिखित उदाहरण पर विचार करें।

String str = new String();

str  = "Hello";
System.out.println(str);  //Prints Hello

str = "Help!";
System.out.println(str);  //Prints Help!

अब, जावा में, स्ट्रिंग ऑब्जेक्ट अपरिवर्तनीय हैं। फिर कैसे आये ऑब्जेक्ट strको "हेल्प!" मान दिया जा सकता है। क्या यह जावा में तार की अपरिवर्तनीयता के विपरीत नहीं है? क्या कोई कृपया मुझे अपरिवर्तनीयता की सटीक अवधारणा समझा सकता है?

संपादित करें:

ठीक। मुझे अब यह मिल रहा है, लेकिन सिर्फ एक अनुवर्ती प्रश्न। निम्नलिखित कोड के बारे में क्या:

String str = "Mississippi"; 
System.out.println(str); // prints Mississippi 

str = str.replace("i", "!"); 
System.out.println(str); // prints M!ss!ss!pp! 

क्या इसका मतलब यह है कि दो वस्तुओं को फिर से बनाया गया है ("मिसिसिपी" और "एम! एस एस एस! पीपी!") और संदर्भ strएक अलग वस्तु को replace()विधि के बाद इंगित करता है ।


str केवल एक संदर्भ ही नहीं वस्तु है
ahmednabil88

मुझे उम्मीद है कि इससे पुष्करराजपुरीरी
स्ट्रींग्स-

जवाबों:


316

strएक वस्तु नहीं है, यह एक वस्तु का संदर्भ है। "Hello"और "Help!"दो अलग-अलग Stringवस्तुएं हैं। इस प्रकार, एक स्ट्रिंग str को इंगित करता है। आप इसे बदल सकते हैं कि यह किस ओर इंगित करता है , लेकिन ऐसा नहीं है जो इसे इंगित करता है

इस कोड को लें, उदाहरण के लिए:

String s1 = "Hello";
String s2 = s1;
// s1 and s2 now point at the same string - "Hello"

अब, वहाँ कुछ भी नहीं है 1 करने के लिए हम क्या कर सकता है s1कि के मूल्य को प्रभावित करती है s2। वे एक ही वस्तु को संदर्भित करते हैं - स्ट्रिंग "Hello"- लेकिन वह वस्तु अपरिवर्तनीय है और इस प्रकार इसे बदला नहीं जा सकता है।

अगर हम ऐसा कुछ करते हैं:

s1 = "Help!";
System.out.println(s2); // still prints "Hello"

यहाँ हम एक वस्तु को परिवर्तित करने और एक संदर्भ को बदलने के बीच का अंतर देखते हैं। s2अभी भी उसी वस्तु की ओर इशारा करता है जो हम शुरू में करते हैंs1 ओर इशारा में इंगित करते हैं। केवल संदर्भ में परिवर्तन s1करने से सेटिंग होती है , जबकि मूल रूप से संदर्भित ऑब्जेक्ट अपरिवर्तित रहता है।"Help!"String

अगर तार परस्पर थे , तो हम कुछ इस तरह कर सकते हैं:

String s1 = "Hello";
String s2 = s1;
s1.setCharAt(1, 'a'); // Fictional method that sets character at a given pos in string
System.out.println(s2); // Prints "Hallo"

ओपी के संपादन का जवाब देने के लिए संपादन करें

यदि आप String.replace (char, char) (अपने JDK इंस्टॉलेशन डायरेक्टरी में src.zip में भी उपलब्ध है ) के सोर्स कोड को देखते हैं - एक प्रो टिप वहाँ देखने के लिए है जब भी आपको आश्चर्य होता है कि वास्तव में कुछ कैसे काम करता है) तो आप देख सकते हैं कि क्या यह निम्न है:

  • अगर एक या एक से अधिक घटनाएं होती हैं oldChar वर्तमान स्ट्रिंग में , तो वर्तमान स्ट्रिंग की एक प्रतिलिपि बनाएँ जहाँ सभी आवृत्तियों oldCharको प्रतिस्थापित किया जाता है newChar
  • अगर द oldChar वर्तमान स्ट्रिंग में मौजूद नहीं है, तो वर्तमान स्ट्रिंग लौटाएं।

तो हाँ, "Mississippi".replace('i', '!')एक नया बनाता हैString वस्तु । फिर, निम्नलिखित रखती है:

String s1 = "Mississippi";
String s2 = s1;
s1 = s1.replace('i', '!');
System.out.println(s1); // Prints "M!ss!ss!pp!"
System.out.println(s2); // Prints "Mississippi"
System.out.println(s1 == s2); // Prints "false" as s1 and s2 are two different objects

अब के लिए आपका होमवर्क यह देखना है कि यदि आप बदलते हैं तो उपरोक्त कोड क्या करता s1 = s1.replace('i', '!');हैs1 = s1.replace('Q', '!'); :)


1 वास्तव में, यह है मे बदलें तार (और अन्य अपरिवर्तनीय वस्तुओं) के लिए संभव। यह प्रतिबिंब की आवश्यकता है और बहुत, बहुत खतरनाक है और कभी भी उपयोग नहीं किया जाना चाहिए जब तक कि आप वास्तव में कार्यक्रम को नष्ट करने में रुचि नहीं रखते।


15
काल्पनिक विधि के लिए +1, यह अपरिवर्तनीय वस्तु और अन्य के बीच अंतर प्रदर्शित करता है।
ज़प्पी

1
सही उदाहरण और स्पष्ट स्पष्टीकरण के लिए धन्यवाद gustafc .... लेकिन क्या आप कृपया प्रश्न में संपादित भाग का उत्तर दे सकते हैं? इससे मेरी समझ स्पष्ट होगी।
लाइट_हैंडल

17
मैंने पहले कभी इस तरह का जवाब नहीं देखा। हर एक विस्तार पर चर्चा की।
माइकल

+1 यहाँ एक विचार है, जावा में अपरिवर्तनीय वस्तुएँ कॉपी-बाय-वैल्यू की तरह हैं, आपके पास एक स्ट्रिंग के 2 संदर्भ हो सकते हैं, लेकिन आपको उन्हें 2 अलग-अलग स्ट्रिंग्स पर विचार करना चाहिए क्योंकि यह अपरिवर्तनीय है, और उनमें से एक के साथ काम करना प्रभावित नहीं करेगा। अन्य
खालिद .K

1
जावा-जितना आपको लगता है कि आप जानते हैं, उतना ही कम आप वास्तव में जानते हैं।
जीशान

23

वह वस्तु जो strसंदर्भों को बदल सकती है, लेकिन वास्तविक Stringवस्तुएं स्वयं नहीं कर सकती हैं।

Stringस्ट्रिंग वाली वस्तुओं "Hello"और "Help!"उनके मूल्यों को बदल नहीं सकते, इसलिए वे अडिग हैं।

Stringवस्तुओं की अपरिवर्तनीयता का मतलब यह नहीं है कि ऑब्जेक्ट को इंगित करने वाले संदर्भ बदल नहीं सकते हैं।

एक तरीका जिसे strसंदर्भ को बदलने से रोका जा सकता है, वह यह है final:

final String STR = "Hello";

अब, एक और असाइन करने की कोशिश Stringकरने के लिए STRएक संकलन त्रुटि का कारण होगा।


लेकिन इस मामले में, स्ट्रिंग ऑब्जेक्ट 'str' है, जिसमें पहले 'Hello' का मान होता है और फिर नए मान 'Help' को असाइन किया जाता है। क्या वास्तव में आप "स्ट्रिंग" युक्त वस्तुओं "हैलो" और "सहायता!" का अर्थ नहीं करते हैं, इसलिए वे अपने मूल्यों को बदल नहीं सकते हैं, इसलिए वे अपरिवर्तनीय हैं। "" मुझे क्षमा करें यदि यह एक मूर्खतापूर्ण प्रश्न है। लेकिन iv को इसे साफ करना
पड़ा

2
क्या आपने सी में प्रोग्राम करने की कोशिश की है? बस संकेत पर प्राइमर पढ़ें और आप कोबर्ड के उत्तर को पूरी तरह से समझ जाएंगे।
रयान फर्नांडिस

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

आप संदर्भों और वस्तुओं को भ्रमित कर रहे हैं - strयह "ऑब्जेक्ट" नहीं है यह ऑब्जेक्ट का संदर्भ है। यदि आपके String str = "Hello";बाद String anotherReference = str;आपके पास 2 स्ट्रिंग ऑब्जेक्ट नहीं हैं, तो आपके पास एक ऑब्जेक्ट (शाब्दिक "हैलो") और 2 संदर्भ हैं ( strऔर anotherReference)।
नैट

मेरे पास संपादित करने के अधिकार नहीं हैं, लेकिन अगर मैंने किया, तो मैं 1 वाक्य के लिए सह-संपादन संपादित करूंगा: "स्ट्रिंग संदर्भ बदल सकते हैं, लेकिन वास्तविक स्ट्रिंग ऑब्जेक्ट्स स्वयं नहीं कर सकते हैं।"
j3App

10

Light_handle मैं आपको कप साइज़ को पढ़ने की सलाह देता हूँ - वैरिएबल और पास-बाय-वैल्यू प्लीज़ (कप साइज़ जारी) के बारे में एक कहानी । ऊपर दिए गए पदों को पढ़ने पर यह बहुत मदद करेगा।

क्या आपने उन्हे पढ़ा है? हाँ। अच्छा।

String str = new String();

यह एक नया "रिमोट कंट्रोल" बनाता है जिसे " str" कहा जाता है और इसे मूल्य new String()(या) में सेट करता है"" ) पर ।

स्मृति में यह बनाता है:

str --- > ""

str  = "Hello";

इसके बाद रिमोट कंट्रोल बदल जाता है " str" लेकिन मूल स्ट्रिंग को संशोधित नहीं करता है""

स्मृति में यह बनाता है:

str -+   ""
     +-> "Hello"

str = "Help!";

इसके बाद रिमोट कंट्रोल बदल जाता है " str" लेकिन मूल स्ट्रिंग को संशोधित नहीं करता है"" या ऑब्जेक्ट को है जो रिमोट कंट्रोल वर्तमान में इंगित करता है।

स्मृति में यह बनाता है:

str -+   ""
     |   "Hello"
     +-> "Help!"

क्या "" और "हेलो" कचरा इकट्ठा हो जाता है?
प्रबीन तिमिना 21

@PrabinTimsina यह वास्तव में एक नया प्रश्न होना चाहिए। इसका उत्तर दिया गया है: stackoverflow.com/questions/15324143/…
माइकल लॉयड ली mlk

9

इसे कुछ हिस्सों में तोड़ने की सुविधा देता है

String s1 = "hello";

यह स्टेटमेंट हेलो में लगातार स्ट्रिंग बनाता है और मेमोरी में लगातार जगह बनाता है अर्थात कॉन्स्टेंट स्ट्रिंग पूल में और इसे रेफरेंस ऑब्जेक्ट s1 में सौंपा जाता है

String s2 = s1;

यह कथन समान स्ट्रिंग हैलो को नए संदर्भ s2 में असाइन करता है

         __________
        |          |
s1 ---->|  hello   |<----- s2
        |__________| 

दोनों संदर्भ एक ही स्ट्रिंग की ओर इशारा कर रहे हैं इसलिए निम्नानुसार समान मूल्य का उत्पादन करते हैं।

out.println(s1);    // o/p: hello
out.println(s2);    // o/p: hello

हालांकि स्ट्रिंग है अपरिवर्तनीय , असाइनमेंट इसलिए संभव हो सकता है एस 1 अब नया मान के पास भेजेगा ढेर

s1 = "stack";    
         __________
        |          |
s1 ---->|  stack   |
        |__________|

लेकिन s2 ऑब्जेक्ट के बारे में क्या है जो हैलो को इंगित कर रहा है जैसा कि यह होगा।

         __________
        |          |
s2 ---->|  hello   |
        |__________|

out.println(s1);    // o/p: stack
out.println(s2);    // o/p: hello

चूंकि स्ट्रिंग अपरिवर्तनीय है जावा वर्चुअल मशीन हमें इसकी विधि द्वारा स्ट्रिंग s1 को संशोधित करने की अनुमति नहीं देगा । यह निम्नानुसार सभी नए स्ट्रिंग ऑब्जेक्ट पूल में बनाएगा।

s1.concat(" overflow");

                 ___________________
                |                   |
s1.concat ----> |  stack overflow   |
                |___________________|

out.println(s1);    // o/p: stack
out.println(s2);    // o/p: hello
out.println(s1.concat); // o/p: stack overflow

ध्यान दें कि यदि स्ट्रिंग उत्परिवर्तनीय होगी, तो आउटपुट होगा

out.println(s1);    // o/p: stack overflow

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

s1 = s1.concat(" overflow");

यहां हम s1 संदर्भ के लिए वापस स्ट्रिंग के संशोधित मूल्य प्रदान कर रहे हैं ।

         ___________________
        |                   |
s1 ---->|  stack overflow   |
        |___________________|


out.println(s1);    // o/p: stack overflow
out.println(s2);    // o/p: hello

इसलिए जावा ने स्ट्रिंग को अंतिम वर्ग के रूप में तय किया अन्यथा कोई भी स्ट्रिंग के मूल्य को संशोधित और बदल सकता है। उम्मीद है कि इससे थोड़ी मदद मिलेगी।


6

पहली बार संदर्भित स्ट्रिंग ऑब्जेक्ट को strपरिवर्तित नहीं किया गया था, जो आपने किया था वह strएक नई स्ट्रिंग ऑब्जेक्ट का संदर्भ था ।


5

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


5

अपने प्रश्न के बदले हुए हिस्से के बारे में, यह कोशिश करें:

String str = "Mississippi"; 
System.out.println(str); //Prints Mississippi 

String other = str.replace("i", "!"); 
System.out.println(str); //still prints Mississippi 
System.out.println(other);  // prints M!ss!ss!pp!

4

हालांकि जावा इसे अनदेखा करने की कोशिश करता है, strलेकिन एक संकेतक से ज्यादा कुछ नहीं है। इसका मतलब यह है कि जब आप पहली बार लिखते हैं str = "Hello";, तो आप एक ऑब्जेक्ट बनाते हैं जो strइंगित करता है। जब आप strलिखकर पुन: असाइन करते हैं str = "Help!";, तो एक नई वस्तु बनाई जाती है और "Hello"जब भी जावा ऐसा महसूस करता है तो पुरानी वस्तु को कचरा एकत्र हो जाता है।


3

अपरिवर्तनशीलता का तात्पर्य है कि एक तात्कालिक वस्तु का मूल्य नहीं बदल सकता है, आप "हेलो" को "सहायता" में कभी नहीं बदल सकते।

चर str एक ऑब्जेक्ट का संदर्भ है, जब आप str को एक नया मान देते हैं, तो आप उस ऑब्जेक्ट का मान नहीं बदल रहे हैं जिसे आप संदर्भित करते हैं, आप किसी भिन्न ऑब्जेक्ट को संदर्भित कर रहे हैं।


3

स्ट्रिंग वर्ग अपरिवर्तनीय है, और आप अपरिवर्तनीय वस्तु का मूल्य नहीं बदल सकते हैं। लेकिन स्ट्रिंग के मामले में, यदि आप स्ट्रिंग के मूल्य को बदलते हैं, तो यह स्ट्रिंग पूल में नई स्ट्रिंग बनाएगा और आपके स्ट्रिंग संदर्भ से उस मान का पुराना नहीं होगा। तो इस तरह से स्ट्रिंग अपरिवर्तनीय है। अपना उदाहरण दें,

String str = "Mississippi";  
System.out.println(str); // prints Mississippi 

यह एक स्ट्रिंग "मिसिसिपी" बनाएगा और इसे स्ट्रिंग पूल में जोड़ देगा ताकि अब str मिसिसिपी की ओर इशारा कर सके।

str = str.replace("i", "!");  
System.out.println(str); // prints M!ss!ss!pp! 

लेकिन उपरोक्त ऑपरेशन के बाद, एक और स्ट्रिंग "एम! एसएस! पीपी!" बनाई जाएगी और इसे स्ट्रिंग पूल में जोड़ा जाएगा। और अब str M-ss की ओर इशारा कर रहा है! ss! pp !, मिसिसिपी नहीं।

तो इस तरह से जब आप स्ट्रिंग ऑब्जेक्ट के मूल्य को बदल देंगे तो यह एक और ऑब्जेक्ट बना देगा और इसे स्ट्रिंग पूल में जोड़ देगा।

चलो एक और उदाहरण है

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

यह तीन लाइन के ऊपर स्ट्रिंग पूल में स्ट्रिंग के तीन ऑब्जेक्ट जोड़ देगा।
1) हैलो
2) वर्ल्ड
3) हैलोवर्ल्ड


2

उपयोग:

String s = new String("New String");
s.concat(" Added String");
System.out.println("String reference -----> "+s); // Output: String reference -----> New String

यदि आप यहाँ देखते हैं तो मैं concatमूल स्ट्रिंग को बदलने के लिए विधि का उपयोग करता हूँ , अर्थात्, "स्ट्रिंग के साथ नया स्ट्रिंग" "जोड़ा गया स्ट्रिंग" है, लेकिन फिर भी मुझे पिछले के रूप में आउटपुट मिला है, इसलिए यह साबित होता है कि आप ऑब्जेक्ट का संदर्भ नहीं बदल सकते हैं स्ट्रिंग क्लास की, लेकिन अगर आप स्ट्रींगबर्स्ट क्लास द्वारा यह बात करते हैं तो यह काम करेगा। इसे नीचे सूचीबद्ध किया गया है।

StringBuilder sb = new StringBuilder("New String");
sb.append(" Added String");
System.out.println("StringBuilder reference -----> "+sb);// Output: StringBuilder reference -----> New String Added String

2

लिनुस तोलवार्ड्स ने कहा:

बोलना आसान है। मुझे कोड दिखाओ

इस पर एक नजर डालिए:

public class Test{
    public static void main(String[] args){

        String a = "Mississippi";
        String b = "Mississippi";//String immutable property (same chars sequence), then same object

        String c = a.replace('i','I').replace('I','i');//This method creates a new String, then new object
        String d = b.replace('i','I').replace('I','i');//At this moment we have 3 String objects, a/b, c and d

        String e = a.replace('i','i');//If the arguments are the same, the object is not affected, then returns same object

        System.out.println( "a==b? " + (a==b) ); // Prints true, they are pointing to the same String object

        System.out.println( "a: " + a );
        System.out.println( "b: " + b );

        System.out.println( "c==d? " + (c==d) ); // Prints false, a new object was created on each one

        System.out.println( "c: " + c ); // Even the sequence of chars are the same, the object is different
        System.out.println( "d: " + d );

        System.out.println( "a==e? " + (a==e) ); // Same object, immutable property
    }
}

आउटपुट है

a==b? true
a: Mississippi
b: Mississippi
c==d? false
c: Mississippi
d: Mississippi
a==e? true

तो, दो बातें याद रखें:

  • स्ट्रिंग्स अपरिवर्तनीय हैं जब तक कि आप एक विधि लागू नहीं करते हैं जो एक नया हेरफेर करता है और (सी एंड डी केस) बनाता है।
  • प्रतिस्थापित विधि एक ही स्ट्रिंग ऑब्जेक्ट देता है यदि दोनों पैरामीटर समान हैं

0

कैसे जावा में स्ट्रिंग अपरिवर्तनीयता को तोड़ने के लिए सोच रहे लोगों के लिए ...

कोड

import java.lang.reflect.Field;

public class StringImmutability {
    public static void main(String[] args) {
        String str1 = "I am immutable";
        String str2 = str1;

        try {
            Class str1Class = str1.getClass();
            Field str1Field = str1Class.getDeclaredField("value");

            str1Field.setAccessible(true);
            char[] valueChars = (char[]) str1Field.get(str1);

            valueChars[5] = ' ';
            valueChars[6] = ' ';

            System.out.println(str1 == str2);
            System.out.println(str1);
            System.out.println(str2);           
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }
}

उत्पादन

true
I am   mutable
I am   mutable

0

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


String a = "a";
System.out.println("String a is referencing to "+a); // Output: a

a.concat("b");
System.out.println("String a is referencing to "+a); // Output: a

a = a.concat("b");
System.out.println("String a has created a new reference and is now referencing to "+a); // Output: ab

0

जावा में, वस्तुओं को आम तौर पर संदर्भों द्वारा एक्सेस किया जाता है। आपके कोड ऑफ स्ट्रिप में एक संदर्भ है जिसे पहले "हैलो" (एक स्वचालित बनाई गई वस्तु या स्थिर पूल से लाया गया ) को सौंपा गया है और फिर आपने एक अन्य वस्तु "हेल्प!" उसी संदर्भ में। ध्यान देने वाली बात यह है कि संदर्भ समान और संशोधित है, लेकिन ऑब्जेक्ट अलग हैं। आपके कोड में एक और चीज जो आपने तीन वस्तुओं तक पहुंचाई है,

  1. जब आपने नया स्ट्रिंग () कहा।
  2. जब आपने "हैलो" असाइन किया।
  3. जब आपने "सहायता" दी।

नया स्ट्रिंग () कॉलिंग एक नया ऑब्जेक्ट बनाता है भले ही यह स्ट्रिंग पूल में मौजूद हो, इसलिए आमतौर पर इसका उपयोग नहीं किया जाना चाहिए। स्ट्रिंग स्ट्रिंग में नए स्ट्रिंग () से बनाई गई स्ट्रिंग डालने के लिए आप intern()विधि का प्रयास कर सकते हैं ।

आशा है कि ये आपकी मदद करेगा।


0

मैं कह सकता हूं कि आप स्ट्रिंग को बदल नहीं सकते। मान लीजिए कि आपके पास स्ट्रिंग x है, जिसका मूल्य "एबीसी" है। अब आप स्ट्रिंग को बदल नहीं सकते हैं, अर्थात, आप "abc" में किसी वर्ण / s को नहीं बदल सकते।

यदि आपको String में किसी वर्ण / अक्षर को बदलना है, तो आप एक वर्ण सरणी का उपयोग कर सकते हैं और इसे म्यूट कर सकते हैं या StringBuilder का उपयोग कर सकते हैं।

String x = "abc";
x = "pot";
x = x + "hj";
x = x.substring(3);
System.out.println(x);

char x1[] = x.toCharArray();
x1[0] = 's';
String y = new String(x1);
System.out.println(y);

आउटपुट:

hj
sj

0

या आप कोशिश कर सकते हैं:

public class Tester
{
public static void main(String[] args)
{
 String str = "Mississippi"; 
 System.out.println(str); // prints Mississippi 
 System.out.println(str.hashCode());

 str = str.replace("i", "!"); 
 System.out.println(str); // prints M!ss!ss!pp! 
 System.out.println(str.hashCode());
 }
 }

इससे पता चलेगा कि हैशकोड कैसे बदलता है।


0

स्ट्रिंग अपरिवर्तनीय का मतलब है कि आप ऑब्जेक्ट को स्वयं नहीं बदल सकते, लेकिन आप ऑब्जेक्ट के संदर्भ को बदल सकते हैं। जब आपने एक = "ty" कहा, तो आप वास्तव में स्ट्रिंग शाब्दिक "ty" द्वारा बनाई गई एक नई वस्तु के संदर्भ को बदल रहे हैं। किसी ऑब्जेक्ट को बदलने का अर्थ है कि उसके किसी एक फ़ील्ड को बदलने के लिए उसके तरीकों का उपयोग करना (या फ़ील्ड सार्वजनिक नहीं हैं और अंतिम नहीं हैं, ताकि उन्हें तरीकों से एक्सेस किए बिना बाहर से अपडेट किया जा सके), उदाहरण के लिए:

Foo x = new Foo("the field");
x.setField("a new field");
System.out.println(x.getField()); // prints "a new field"

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

String s = "some text";
s.substring(0,4);
System.out.println(s); // still printing "some text"
String a = s.substring(0,4);
System.out.println(a); // prints "some"

0

यहां अपरिवर्तनीयता का अर्थ है कि उदाहरण अन्य संदर्भ को इंगित कर सकता है लेकिन मूल संदर्भ में स्ट्रिंग की मूल सामग्री को संशोधित नहीं किया जाएगा। मुझे आपके द्वारा दिए गए पहले उदाहरण से समझाते हैं। पहली बार "हैलो" की ओर इशारा कर रहा है, यह ठीक है। दूसरी बार "मदद" की ओर इशारा करते हुए। यहाँ str ने "Help" की ओर इशारा करना शुरू किया! और "हैलो" स्ट्रिंग का संदर्भ खो गया है और हम इसे वापस नहीं पा सकते हैं।

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


0

उत्तर के लिए देर से, लेकिन जावा में स्ट्रिंग वर्ग के लेखक से एक संक्षिप्त संदेश डालना चाहता था

तार स्थिर हैं; उनके मान बनाए जाने के बाद उन्हें बदला नहीं जा सकता। स्ट्रिंग बफ़र्स म्यूटेबल स्ट्रिंग्स का समर्थन करते हैं। क्योंकि स्ट्रिंग ऑब्जेक्ट अपरिवर्तनीय हैं, उन्हें साझा किया जा सकता है।

यह इस दस्तावेज से प्राप्त किया जा सकता है कि कुछ भी जो स्ट्रिंग को बदलता है, अलग वस्तु लौटाता है (जो नया या पुराना और पुराना हो सकता है)। इस बारे में इतना सूक्ष्म संकेत समारोह के हस्ताक्षर से नहीं आना चाहिए। इसके बारे में सोचें, 'उन्होंने एक वस्तु पर एक समारोह क्यों बनाया, स्थिति के बजाय एक वस्तु लौटा दी?'।

public String replace(char oldChar, char newChar) 

इसके अलावा एक और स्रोत जो इस व्यवहार को स्पष्ट करता है (फ़ंक्शन प्रलेखन से बदलें)

नए तार में पुराने तार की सभी घटनाओं को बदलने के परिणामस्वरूप एक नया स्ट्रिंग देता है।

स्रोत: https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#replace(char,%20char)

  • लेखक ली बॉयटन
  • लेखक आर्थर वैन हॉफ
  • लेखक मार्टिन बुचोलज़
  • लेखक उल्फ़ ज़िबिस

स्रोत: स्ट्रिंग का JavaDoc


0

ऑब्जेक्ट स्ट्रिंग - विधियों को "अपरिवर्तनीय" बनाया जाता है। यह क्रिया कोई परिवर्तन नहीं पैदा करती है: "पत्र.रेप (" बीब "," आ "));"

लेकिन डेटा असाइन करने से स्ट्रिंग्स सामग्री को बदलने का कारण बनता है:

    letters = "aaa";
    letters=null;
    System.out.println(letters);
    System.out.println(oB.hashCode());
    System.out.println(letters);
    letters = "bbbaaa";
    System.out.println(oB.hashCode());
    System.out.println(letters);

// स्ट्रिंग ऑब्जेक्ट का हैशकोड नहीं बदलता है।


0

तो HELLOअपने स्ट्रिंग है, तो आप बदल नहीं सकते HELLOकरने के लिए HILLO। इस संपत्ति को अपरिवर्तनीय संपत्ति कहा जाता है।

HELLO स्ट्रिंग को इंगित करने के लिए आपके पास कई पॉइंटर स्ट्रिंग चर हो सकते हैं।

लेकिन अगर HELLO char Array है तो आप HELLO को HILLO में बदल सकते हैं। उदाहरण के लिए,

char[] charArr = 'HELLO';
char[1] = 'I'; //you can do this

प्रोग्रामिंग भाषाओं में अपरिवर्तनीय डेटा चर होते हैं ताकि इसे कुंजी, मूल्य जोड़ी में कुंजी के रूप में उपयोग किया जा सके।


0

मैं इसे सरल उदाहरण के साथ समझाऊंगा


किसी भी वर्ण सरणी पर विचार करें: उदाहरण के लिए char a [] = {'h', 'e', ​​'l', 'l', 'o'}; और एक स्ट्रिंग: स्ट्रिंग s = "हैलो";


चरित्र सरणी पर हम सरणी को पुनरावृत्त करते हुए केवल पिछले तीन अक्षरों को प्रिंट करने जैसे ऑपरेशन कर सकते हैं; लेकिन स्ट्रिंग में हमें नई स्ट्रिंग ऑब्जेक्ट बनाना होगा और आवश्यक स्ट्रिंग को कॉपी करना होगा और इसका पता नए स्ट्रिंग ऑब्जेक्ट में होगा।

जैसे

***String s="hello";
String s2=s.substrig(0,3);***

इसलिए s2 में "हेल" होगा;


-1

जावा में अपरिवर्तनीय और अंतिम में स्ट्रिंग का मतलब है कि इसे बदला या संशोधित नहीं किया जा सकता है:

मामला एक:

class TestClass{  
 public static void main(String args[]){  
   String str = "ABC";  
   str.concat("DEF");  
   System.out.println(str);  
 }  
} 

आउटपुट: एबीसी

कारण: ऑब्जेक्ट संदर्भ str वास्तव में एक नई ऑब्जेक्ट "DEF" नहीं बनाया गया है जो कि पूल में बना है और जिसका कोई संदर्भ नहीं है (यानी खो गया है)।

केस 2:

class TestClass{  
 public static void main(String args[]){  
   String str="ABC";  
   str=str.concat("DEF");  
   System.out.println(str);  
 }  
}  

आउटपुट: ABCDEF

कारण: इस मामले में str अब एक नई वस्तु "ABCDEF" का जिक्र कर रहा है, इसलिए यह ABCDEF को प्रिंट करता है अर्थात पिछली str ऑब्जेक्ट "ABC" बिना किसी संदर्भ के पूल में खो जाती है।


-1

क्योंकि स्ट्रिंग अपरिवर्तनीय है, इसलिए यदि आप स्ट्रिंग के फ़ंक्शन का लौटाया गया मान स्ट्रिंग को नहीं सौंपेंगे, तो आपके प्रश्न में स्वैप फ़ंक्शन का मान वापस करने के लिए मान लौटाया जाएगा।

s = swap (s, n1, n2); फिर स्ट्रिंग s का मान बदल जाएगा।

जब मैं कुछ क्रमपरिवर्तन स्ट्रिंग प्राप्त करने के लिए कार्यक्रम लिख रहा था तो मुझे अपरिवर्तित मूल्य भी मिल रहा था (हालांकि यह सभी क्रमपरिवर्तन नहीं दे रहा है लेकिन यह आपके प्रश्न का उत्तर देने के लिए उदाहरण के लिए है)

यहाँ एक उदाहरण है।

> import java.io.*;  public class MyString { public static void
> main(String []args)throws IOException {  BufferedReader br=new
> BufferedReader(new InputStreamReader(System.in));  String
> s=br.readLine().trim(); int n=0;int k=0;  while(n!=s.length()) {
> while(k<n){  swap(s,k,n); System.out.println(s); swap(s,k,n); k++; }
> n++; } }  public static void swap(String s,int n1,int n2) { char temp;
> temp=s.charAt(n1); StringBuilder sb=new StringBuilder(s);
> sb.setCharAt(n1,s.charAt(n2)); sb.setCharAt(n2,temp); s=sb.toString();
> } }

लेकिन मुझे ऊपर दिए गए कोड से स्ट्रिंग के अनुमत मान नहीं मिल रहे थे। इसलिए मैंने स्ट्रिंग को स्वैप फ़ंक्शन के दिए गए मान को सौंपा और स्ट्रिंग के परिवर्तित मूल्य प्राप्त किए। लौटे मूल्य को निर्दिष्ट करने के बाद मुझे स्ट्रिंग के अनुमत मान मिले।

/import java.util.*; import java.io.*; public class MyString { public static void main(String []args)throws IOException{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); 
String s=br.readLine().trim(); int n=0;int k=0; 
while(n!=s.length()){ while(k<n){ s=swap(s,k,n); 
System.out.println(s); s=swap(s,k,n); k++; } n++; } } 
public static String swap(String s,int n1,int n2){
char temp; temp=s.charAt(n1); StringBuilder sb=new StringBuilder(s); sb.setCharAt(n1,s.charAt(n2)); sb.setCharAt(n2,temp); s=sb.toString(); return s; } }

-1
    public final class String_Test {

    String name;
    List<String> list=new ArrayList<String>();

    public static void main(String[] args) {

        String_Test obj=new String_Test();
        obj.list.add("item");//List will point to a memory unit- i.e will have one Hashcode value #1234

        List<String> list2=obj.list; //lis1 also will point to same #1234

        obj.list.add("new item");//Hashcode of list is not altered- List is mutable, so reference remains same, only value in that memory location changes

        String name2=obj.name="Myname"; // name2 and name will point to same instance of string -Hashcode #5678
        obj.name = "second name";// String is Immutable- New String HAI is created and name will point to this new instance- bcoz of this Hashcode changes here #0089

        System.out.println(obj.list.hashCode());
        System.out.println(list2.hashCode());
        System.out.println(list3.hashCode());

        System.out.println("===========");
        System.out.println(obj.name.hashCode());
        System.out.println(name2.hashCode());
    }
}

कुछ इस तरह से बाहर का उत्पादन होगा

1419358369 1419358369

103056 65078777

अपरिवर्तनीय वस्तु का उद्देश्य यह है कि एक बार असाइन किए जाने के बाद इसका मूल्य परिवर्तित नहीं किया जाना चाहिए। कार्यान्वयन के आधार पर आप इसे बदलने की कोशिश में हर बार नई वस्तु वापस करेंगे। नोट: स्ट्रिंग के बजाय स्ट्रिंगबफ़र का उपयोग इससे बचने के लिए किया जा सकता है।

आपके अंतिम प्रश्न के लिए: u में एक संदर्भ होगा, और स्ट्रिंग पूल में 2 तार होंगे .. संदर्भ को छोड़कर m! Ss! Pp को इंगित करेंगे।

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