Deepeshkumar
Deepeshkumar

Reputation: 443

Strings are immutable then how the replace() works?

I was trying to replace the first letter/char of a string by it's last one and last one by it's first one. E.g. abcd => dbca. Strings are immutable in Java then how can we explain the behavior of this program? Please have a look at final output. str1 has no char 'a' but in final output it appears unexpectedly.. how? //The argument of frontBack() is String "abcd".

 public static void frontBack(String str) {
   String first= ""+str.charAt(0);
   System.out.println("first char is "+first);
   String last = ""+str.charAt(str.length()-1);
   System.out.println("last char is "+last);
   String str1;
   str1 = str.replace(""+str.charAt(0),last);
   System.out.println("String str1 is => "+str1);
   String str2 ;
   str2 = str1.replace(""+str1.charAt(str1.length()-1),first);
   System.out.println("String str2 is derived from str1(dbcd) which has no 'a' but o/p is =>  "+str2);    
  }
 /* Have a look at output:
                        first char is a
                        last char is d
                        String str1 is => dbcd
                        String str2 is derived from str1 i.e. "dbcd" which has no 'a' in it but o/p is =>  abca*/

Upvotes: 3

Views: 8887

Answers (2)

Jesper
Jesper

Reputation: 206786

First of all, you have to understand that variables in Java (of non-primitive types) are not objects themselves, they are references to objects. Class String is immutable, which means that once a String object has been created, there is no way to change the content of the object. However, you can make a String variable refer to a different String object.

Let's look what is happening line by line. We start with str referring to a String object with the content "abcd".

String first= ""+str.charAt(0);

This makes the variable first refer to a new String object with the content "a".

String last = ""+str.charAt(str.length()-1);

This makes the variable last refer to a new String object containing only the last character of the String object that str refers to. So, last refers to a String object with the content "d".

String str1;
str1 = str.replace(""+str.charAt(0),last);

The replace() method takes two arguments: the substring you want to find, and the string to replace it with. Note that replace() does not change the original String object; it returns a new String object with all occurrences of the first argument replaced by the second argument. See the API documentation.

""+str.charAt(0) is "a" and last is "d", so this line is equivalent to:

str1 = str.replace("a", "d");

After this line, str still refers to the original String with content "abcd" and str1 refers to a new String with content "dbcd".

String str2 ;
str2 = str1.replace(""+str1.charAt(str1.length()-1),first);

In this line, the first argument to replace() is: ""+str1.charAt(str1.length()-1) which is "d" (the last letter of the String that str1 refers to).

The second argument is first which is "a".

So this line is equivalent to:

str2 = str1.replace("d", "a");

After this line, str1 still refers to the String with content "dbcd", and str2 refers to a new String object where all the letters d have been replaced by a, so: "abca".

Upvotes: 5

Peter Lawrey
Peter Lawrey

Reputation: 533472

Strings are immutable in Java then how can we explain the behavior of this program?

str1 = str.replace(""+str.charAt(0),last);

This method takes a String which is immutable and creates a new String which is immutable. Immutable doesn't mean the String cannot be created.

Note: if you want to manipulate some text you can use a StringBuilder which is mutable. You can create this from a String and you can create a new String from it. This is often, but not always used, sometimes a char[] is used directly for performance reasons.

the new string which is created has no char 'a' but in final output it appears unexpectedly.

This is where using a your debugger would help. You would see that

String first= ""+str.charAt(0); // first = "a"

and later when you do

str2 = str1.replace(""+str1.charAt(str1.length()-1),first);

this is the same as

str2 = str1.replace("d", "a");

so it should be no surprise that the ds are replaced by as

I am using replace() not replaceAll()

From the Javadoc for String.replace(CharSequence, CharSequence)

Replaces each substring of this string that matches the literal target sequence with the specified literal replacement sequence.

Upvotes: 6

Related Questions