1

Yes, I know Java's Strings are immutable, but still, that alone does not explain why this won't work for me...
I ran into this problem when I tried to convert an array of strings (String[]) to one string of the form: ('String[0]','String[1]',...,'String[n]').
For example, given the following array:

String[] array=new String[3];
array[0]="Jake";
array[1]="Mishel";
array[2]="Dan";

I wanted to create the string: ('Jake','Mishel','Dan')
But, the way to do it is not the purpose of this post...
What I'm interested to know is, why does this work:

 String[] array=new String[3];
 array[0]="Jake";
 array[1]="Mishel";
 array[2]="Dan";
 for (int i=0; i<array.length; i++) {
 array[i]=array[i]+"'";
 array[i]="'"+array[i];
 }
 String str=Arrays.toString(array);
 str=str.replace('[','(');
 str=str.replace(']',')');
 System.out.println(str); //produces ('Jake','Mishel','Dan'), as desired

But this doesn't:

 String[] array=new String[3];
 array[0]="Jake";
 array[1]="Mishel";
 array[2]="Dan";
 for (String str: array) {
 str=str+"'";
 str="'"+str;
 }
 String str=Arrays.toString(array);
 str=str.replace('[','(');
 str=str.replace(']',')');
 System.out.println(str); //produces wrong output: (Jake,Mishel,Dan)

?

asked Aug 13, 2014 at 18:51
4
  • what is the error you get? Commented Aug 13, 2014 at 18:53
  • There's no error. just wrong output. Commented Aug 13, 2014 at 18:54
  • Your loop creates local copies of the array into a new String object while, in the first exemple, the reference of element in the array is passed, its value is directly modified Commented Aug 13, 2014 at 18:56
  • 3
    In general, "<Major programming language>'s <major feature> doesn't work" is false - you can almost always assume that you've just made an error. "Why can't I modify a String element of an array in a for each loop?" might be a better title. Commented Aug 13, 2014 at 19:00

6 Answers 6

4

It doesn't work because in the second one, you're extracting the value of the string from each index in the array as str, and then making changes to str, not the string in the array (Technically not changes, replacing would be a better word). In the first one, you rewrite the index of the array with a new value.

In effect, in a for each loop you're working with a local variable with the same value as the global variable. However, this is a new variable, and so it doesn't have a scope outside of your loop. In the regular for loop, you explicitly update the item located at each index of the array.

answered Aug 13, 2014 at 18:54

4 Comments

I imagine there are ways to write the regular for loop so that it has the same problem.
This is very misleading -- you are not working with copies in a foreach! Unless you explicitly make a copy, you are working with local variables, which are something totally different! What's important to understand here is that String specifically returns a new object when you "add" to it.
Hmm, how is it misleading? It's a local variable that takes its value from the global variable. Isn't that a copy? Regardless you make a good point about the scope which I'll add in.
Re: "changes to str...technically not changes". No, the second example changes the value of str each time around the loop. str is not a String: str is a local variable that refers to a String. And that's the problem! The reference initially stored in str is a copy of the reference stored in the array. After str is updated to refer to a new String, the array still refers to the old String. The first example updated the references in the array.
3

This code

for (String str: array) {
 str = str+"'";
 str = "'"+str;
}

Is equivalent of

for (int i=0; i<array.length; i++) {
 //Temporary local variable named str which holds value from array
 String str = array[i];
 str = str+"'";
 str = "'"+str;
}

So by str=str+"'"; you are reassigning local variable which doesn't affect array, while by array[i]=array[i]+"'"; you actually update value in array.


BTW: Java 8 adds StringJoiner class which can be used like

StringJoiner sj = new StringJoiner("','", "'", "'");//delimite, prefix, suffix
for (String str : array)
 sj.add(str);
System.out.println(sj);

to produce 'Jake','Mishel','Dan'


We can also create one-line solution by using join method added to String

System.out.println("'"+String.join("','", array)+"'");
// ^^^ - delimiter
answered Aug 13, 2014 at 18:57

Comments

1
for (String str: array) { // read as for each string str in Array array. str contains same value as arr[i] 
 str=str+"'"; 
 str="'"+str;
 }

Is your problem. you are working on copies of the actual strings of the array. You are not working on the array.

answered Aug 13, 2014 at 18:54

Comments

1

Inside your loop str is effectively a local variable; it's not a reference to the element of the array but rather a new String which is a copy of that element. So your changes to str do not change elements of the array.

answered Aug 13, 2014 at 18:54

Comments

1

The reason this

for (String str: array) {
 str=str+"'";
 str="'"+str;
}

Doesn't work is because you are modifying the reference String str (which is independent of the array being a local copy).

First, you could declare and initialize your array with

String[] array = { "Jake", "Mishel", "Dan" };

Then

for (int i = 0; i < array.length; i++) {
 array[i] = array[i] + "'";
 array[i] = "'" + array[i];
}

Should probably be

for (int i = 0; i < array.length; i++) {
 array[i] = "'" + array[i] + "'";
}

Finally, you could write

str=str.replace('[','(');
str=str.replace(']',')');

as

str = str.replace('[', '(').replace(']', ')');

Putting it together

String[] array = { "Jake", "Mishel", "Dan" };
for (int i = 0; i < array.length; i++) {
 array[i] = "'" + array[i] + "'";
}
String str = Arrays.toString(array);
str = str.replace('[', '(').replace(']', ')');
System.out.println(str);

Output is

('Jake', 'Mishel', 'Dan')
answered Aug 13, 2014 at 19:06

Comments

0

It does not work because str is not the String in the array, it is a local variable that has the same characteristics as the "real" String in the array / a copy of the String in the array.

answered Aug 13, 2014 at 19:07

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.