1

I was always told strings in java are immutable, unless your going to use the string builder class or string writter class.

Take a look at this practice question I found online,

Given a string and a non-negative int n, return a larger string that is n copies of the original string.

stringTimes("Hi", 2) → "HiHi"
stringTimes("Hi", 3) → "HiHiHi"
stringTimes("Hi", 1) → "Hi"

and the solution came out to be

Solution:

public String stringTimes(String str, int n) {
  String result = "";
  for (int i=0; i<n; i++) {
    result = result + str;  // could use += here
  }
  return result;
}

As you see in the solution our 3rd line assigns the string , then we change it in our for loop. This makes no sense to me! (I answered the question in another nooby way ) Once I saw this solution I knew I had to ask you guys.

Thoughts? I know im not that great at programming but I haven't seen this type of example here before, so I thought I'd share.

GBlodgett
  • 12,704
  • 4
  • 31
  • 45
RocStream
  • 67
  • 7
  • 2
    You're confusing the variable (which contains a reference) with the object that it points to. – chrylis -cautiouslyoptimistic- May 08 '18 at 00:34
  • you mean the String result="" line? is that not a variable deceleration and assigning line. Once that empty quotation is allocated in memory for the variable how can it be altered like they did? – RocStream May 08 '18 at 00:36
  • Think of it like this... `someVar = Thing1; someVar = Thing2`. Has `Thing1` been changed (mutated)? No, `someVar` is just a reference to a different object. – Phil May 08 '18 at 00:40
  • I have a feeling some unrecognized genius computer scientist is writing the answer at this moment lol, all I can wonder now is what else have I been told thats a lie from my college professor 2 semesters ago. – RocStream May 08 '18 at 00:41
  • 2
    I'm voting to close this question as off-topic because it is just a misunderstanding about assignment vs mutability – Phil May 08 '18 at 00:41
  • ??? @chrylis already wrote the answer -- you're confusing variable with object. This is a very basic distinction and one that you'll want to study and know cold to progress. – Hovercraft Full Of Eels May 08 '18 at 00:42
  • but then why does it say all over the internet and coding books strings are immutable. I understand what your saying, why can we re assign the string to another reference. – RocStream May 08 '18 at 00:43
  • 1
    You still seem to be unclear on the definition of mutability / immutable objects. Have a read ~ https://en.wikipedia.org/wiki/Immutable_object – Phil May 08 '18 at 00:44
  • So from what im understanding I can change a strings assignment if I am going to update its assignment with another reference stored in memory? – RocStream May 08 '18 at 00:44
  • 2
    Yes, exactly correct. You're changing the object that is referenced by the String variable. You're not mutating any String object after creation. – Hovercraft Full Of Eels May 08 '18 at 00:46
  • String or anything else, you can always assign a new stuff to a variable unless that variable is marked final. That has absolutely nothing to do with modifying the content of whatever object that variable may have pointed to before you assign something else to it. – kumesana May 08 '18 at 00:46
  • OK I got it. thanks guys, I appreciate all your comments. btw phil you should put something for a answer so I can give you the points bro – RocStream May 08 '18 at 00:47

3 Answers3

4

The trick to understanding what's going on is the line below:

result = result + str;

or its equivalent

result += str;

Java compiler performs a trick on this syntax - behind the scene, it generates the following code:

result = result.concat(str);

Variable result participates in this expression twice - once as the original string on which concat method is called, and once as the target of an assignment. The assignment does not mutate the original string, it replaces the entire String object with a new immutable one provided by concat.

Perhaps it would be easier to see if we introduce an additional String variable into the code:

String temp = result.concat(str);
result = temp;

Once the first line has executed, you have two String objects - temp, which is "HiHi", and result, which is still "Hi". When the second line is executed, result gets replaced with temp, acquiring a new value of "HiHi".

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
2

If you use Eclipse, you could make a breakpoint and run it step by step. You will find the id (find it in "Variables" View) of "result" changed every time after java did

result = result + str;

On the other hand, if you use StringBuffer like

StringBuffer result = new StringBuffer("");
for(int i = 0; i < n; i++){
    result.append(str);
}

the id of result will not change.

Peter.Ge
  • 41
  • 4
  • 1
    Almost perfect. For performance, you should use the `StringBuilder` class. `StringBuffer` is thread safe, so slower, and you usually dont need that. – JayC667 May 08 '18 at 01:31
1

String objects are indeed immutable. result is not a String, it is a reference to a String object. In each iteration, a new String object is created and assigned to the same reference. The old object with no reference is eventually destroyed by a garbage collector. For a simple example like this, it is a possible solution. However, creating a new String object in each iteration in a real-world application is not a smart idea.

evnica
  • 300
  • 3
  • 11