This question already has answers here:
String can't change. But int, char can change
(7 answers)
Closed 8 years ago.
I am confuse about String and String Builder. Here is my simple code
StringBuilder sb1 = new StringBuilder("123");
String s1 = "123";
sb1.append("abc");
s1.concat("abc");
System.out.println(sb1 + " " + s1);
sb1 output for 123abc. It is ok! because it use append method.But String s1 should be abc123
but it output is abc. Why? And what is concat method purpose? Please explain me.
Thank you
.But String s1 should be abc123 but it output is abc.
Strings are immutable in Java. concat doesn't change the existing string - it returns a new string. So if you use:
String result = s1.concat("abc");
then that will be "123abc" - but s1 will still be "123". (Or rather, the value of s1 will still be a reference to a string with contents "123".)
The same is true for any other methods on String which you might expect to change the contents, e.g. replace and toLowerCase. When you call a method on string but don't use the result (as is the case here), that's pretty much always a bug.
The fact that strings are immutable is the whole reason for StringBuilder existing in the first place.
concat function not change the string but it returns the result which is not assigned in your case:
String concat(String textToAppend)
so change:
s1 = s1.concat("abc");
string objects are immutable. Immutable simply means unmodifiable or unchangeable
but if you give
String result = s1.concat("abc");
output is 123abc
and
StringBuilder are mutable
you can perform changes
s1.concat("abc") will create a new object in heap with the "abc" concatenated to s1. but s1 is still pointing to original s1 which is "123". so you need to make your s1 reference to point to new object using s1 = s1.concat("abc");
Related
This question already has answers here:
Java String Instantiation
(3 answers)
Closed 5 years ago.
I came across a question asking the output of the below:
String s1 = "String 1";
String s2 = "String 2";
String s3 = s1 + s2;
String s4 = "String 1" + "String 2";
System.out.println(s3==s4);
Output - false
Now, since the strings are not created using new operator, so the objects are created in the string pool, so as per my understanding s1 + s2 and "String 1" + "String 2" should be equal, and s3==s4 should be true.
But it is not happening in real. Can any one please explain this?
The concatenation is happening at runtime, unless both operands are compile-time constant expressions.
Put a final modifier before s1 and s2, and the result will be true, because the compiler will simply replace
String s3 = s1 + s2;
by
String s3 = "String 1String 2";
If you don't, a new String is created at runtime, by appending both strings to a StringBuilder and getting the result.
Note that, although that is interesting from an intellectual point of view, in practice, you shouldn't care about that performance optimization, and always compare Strings with equals().
This line compare memory addresses of two strings. Because of both are separate objects and output will be false.
s3==s4
You need to compare using equals()
System.out.println(s3.equals(s4));
equals() is compare value of object not address.
This question already has answers here:
Strange behavior with string interning in Java
(4 answers)
Closed 5 years ago.
I was reading about String in java and was trying to understand it.
At first, it was easy how String s1="11" and String s2=new String ("11") works(created) and I understood intern method also.
But I came across this example (Given by a friend) and made me confused about everything.
I need help to understand this.
String s1 = new String(new String("2")+new String("2"));
s1.intern();
String s2="22";
System.out.print(s1==s2); //=>true as output.
String s3 =new String (new String("2")+new String("2"));
s3.intern();
String s4="22";
System.out.print(s3==s4); //=>false as output.
Answer of this code is true and false.
Part for S1 and s2 was good and was true according to my understanding but the second part I didn't understand.
Hope someone can break the code line by line and help me understand.
s1.intern(); adds s1 to the pool of strings, therefore the string "22" is now in the pool of strings. Therefore when you write s2 = "22" that's the same "22" as s1 and thus s1 == s2.
s3.intern() does NOT add s3 to the pool of strings because the string "22" is already there.
s3.intern() does return that same "22" which is s1 BUT IT IS NOT USED. Therefore s3 is not equal s4.
In java exist the heap and the stack,
Heap is where all Objects are saved
stack is where vars are saved
Now also exist another kind of list for Strings and Integers (numbers)
As you know a String can be created in some ways like
like new String("word") or just = "word" when you use the first way you create a new object (heap) when you use the other you save the word in a stack of words (Java engenniers thought it would be good if you don't create manny objects or words are repeated so they created an special stack for words, same for Integers from 0 to 127) So as I said You have to know that there is an stack and a Heap look at this example
String wordOne ="hola";
String wordTwo = "hola";
String wordTres = "hola";
System.out.println(wordOne == wordTwo);
System.out.println(wordTres == wordTwo);
System.out.println(wordOne == wordTres);
String wordFour = new String("hola");
System.out.println(wordOne == wordFour);
Integer uno = 127;
Integer dos = 127;
System.out.println(uno == uno);
Integer tres = 128;
Integer cuatro = 128;
System.out.println(tres == cuatro);
String x = "word"; is saved in an special Stack
String y = new String("it is not");
But tbh I don't remeber so well the rules for tha stack, but in any case i recomend you to compare all words using wordX.equals(wordY)
An also numbers in objects could be compared using == from 0 to 127 but the same if you use objects use equals, although using numbers there is a better do to do it in spite of use equals, convert one number to a primitive value (the memory will be better)
When you are making string with new keyword,JVM will create a new string object in normal(non pool) heap memory and the literal will be placed in the string constant pool. In your case, The variable s1 will refer to the object in heap(non pool).
String s1 = new String(new String("2")+new String("2"));
But in the next line your are calling intern() method.
When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
Check Javadocs.
As "22" is not in string pool, a new string literal "22" will be created and a reference of it will be returned. When you are writing:
String s2="22";
it simply refers "22" in string pool. But calling s3.intern() will not create a new string literal as "22" exists in the pool. Check the Javadocs for intern() again. It says if exists in pool, then string from the pool is returned not reference. So, this time s3 references to a different object.
But s4 is referred to same object as s1,s2.
You can print the objects hashcode for checking if the are same or not. Like:
System.out.println(System.identityHashCode(s1));
Notice that the type String is capitalized and is not one of Java's 8 primitive types (int, boolean, double, char, etc.). This indicates that any instance of a String is an object that was built using the 'blueprint' of the class String. Because variables in Java that refer to objects only store the memory address where the actual object is stored, when you compare Strings with == it compares memory location.
String str1 = new String("hello");
String str2 = str1; //sets str1 and str2 pointing to same memory loc
if (str1 == str2){
//do stuff; the code will enter this if-statement in this case
}
The way to compare the values within objects in Java is with equals(), such as:
String str1 = new String("hello");
String str2 = new String("hello"); //str2 not same memory loc as str1
if (str1.equals(str2)){
//do stuff; the code will enter this if-statement in this case
}
This is a common error for beginners, since the primitive types are not objects and you CAN compare two ints for equality like:
int one = 1; //primitive types are NOT objects
int two = 2; //notice when I make an int, I don't have to say "new"
//which means a new **object**
if (int1 == int2) {
//do stuff; in this case the program will not enter this if-statement
}
It seems that you understand everything but the meaning of the very last line. See my comment on the last line.
String s1 = new String(new String("2")+new String("2")); //declare AND initialize s1 as a new String object
s1.intern();
String s2="22"; //declare a new variable s2 and point it to the same object that s1 is pointing to
System.out.print(s1==s2);
String s3 =new String (new String("2")+new String("2"));
s3.intern();
String s4="22";
System.out.print(s3==s4); //check if s3 and s4 are stored in the same memory location = FALSE
In java object1 == object2 means
that do object1 and object2 have the same address in memory?
object1.equals(object2)
means are they equal, for example do they have the same values of all fields?
So, For two Strings S1 and S2,
string1.equals(S2) means, do they have the same characters in the same sequence?
S1 == S1 means are string1 and string2 stored at the same address in memory?
This question already has answers here:
What is Java String interning?
(8 answers)
What is the difference between "text" and new String("text")?
(13 answers)
Closed 6 years ago.
This two codes have defferent outputs and i don't know why.
String a="abc";
String b="abc";
System.out.println(a==b + " " + a.equals(b));
The output is "true true"
String a="abc";
String b=new String("abc");
System.out.println(a==b + " " + a.equals(b));
The output is "false true"
when you use this
String a="abc";
String b="abc";
the java creates only one object in memory which is abc and here a and b are pointing to same object and == don't check the string content instead it check the reference value. but as soon as you do this
String b=new String("abc");
java creates a new object b in memory which is different from a ,now b and a are pointing to two different objects hence if you compare contents with equals function result will be true but if you compare reference now, result will be false
Read about it's usage
This has to be a duplicate of a large number of questions, but I will comment by saying that when you do the following:
String a = "abc";
String b = "abc";
The JVM creates a single String object in the constant pool which contains the String abc. Hence, the a and b Strings simply point to the same string in the pool.
However, when you do the following:
String a = "abc";
String b = new String("abc");
a new object is created even though abc already exists in the pool. Hence the comparison a == b returns false, although the contents of both these strings remains equivalent.
Studying for OCAJ7
I know String objects are immutable. I know using methods like .concat() on a String object will just create a new String object with the same reference name. I'm having a hard time, however, with wrapping my head around the following:
String str1 = "str1";
String str2 = "str2";
System.out.println( str1.concat(str2) );
System.out.println(str1);
// ouputs
// str1str2
// str1
String str3 = "fish";
str3 += "toad";
System.out.println(str3);
// outputs
// fishtoad
If strings are immutable, why does using += to concatenate affect the original String object, but .concat() does not? If I only want a String to concatenate with using +=, is using String better than using StringBuilder, or vice versa?
because you are catching the reference of newly generated String instance in str3
str3 += "toad";
is
str3 = str3 + "toad"
The concat method is more like + than +=. It returns the new string; it doesn't modify the original string or the argument (Strings are immutable).
str1.concat(str2)
is equivalent to str1 + str2, so str1 isn't modified, and the result is discarded.
However, += also assigns the result back to the left side, and str3 now refers to the new string. That's the difference.
Yes you are right Strings are immutable.
But when you write str1.concat(str2) inside System.out.println() you are printing the result returned by the concat() function.The result is a new String which is outputted on the console.
You haven't assigned the value to str1.
But when you write += you are first concatenating something to the String the then assigning the reference back to str1.
This explains the output.
What's happening here is that String.concat(String); does not actually combine str1 and str2 together, instead it returns a new String object that is equivalent to str1str2. When you use str1 += str2, you are actually combining the variables, and then putting the value into str1.
str3 += "toad" means
str3 = str3 + "toad";
So you concatenate and assign the result back to str3
concat() method creates a new string. You have to remember that Strings in Java are immutable.
str1 will point to the newly created string if the o/p is assigned to it,
str1 = str1.concat(str2);
otherwise str1 continues to point to the old string.
If you are going to concat multiple strings together in a loop, then it is better to use StringBuilder
Above you are not changing the reference of str1 in System.out.println(str1.concat(str2) ) so it is temporary storing the reference of str1.concat(str2).
But in str3+=str4 whole reference get moved to "fishtoad" therefore it get changed.But again if you defined a string str5="fish" then it reference back to previous location which was referencing by str3.
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
String s1 = new String("anil");
String s2 = s1.toUpperCase();
String s3 = s1.toLowerCase();
System.out.println(s1 == s2);
System.out.println(s1 == s3);
if string object created in heap then both are false.But it gives false,true.
String s1 = new String("anil");
This statement creates a new object
And this ,
String s3 = s1.toLowerCase();
points the location of 1st object that is s1
And thats the reason you are getting true for second condition
Also see how java handles strings to get a clear understanding
Hope this helps!!
There are four String objects here:
the literal, created by the compiler and classloader
s1, created by new String()
s2, created by toUpperCase()
s3, created by toLowerCase().
No two of them are equal via the == operator.
Except that toLowerCase() may return the same object if it is already lowercase. There's nothing in the Javadoc about that, so any such behaviour in an implementation cannot be relied on.
Here S1 object will be created in heap. Its value is stored in the constant string pool.
S2 is String literal not an object. So first JVM will check whether the string is there in constant pool. If String is there constant pool it will not create new object. It will return reference of the object available.
Here the s1.toUpper will return "ANIL". "ANIL" is not in the constant pool. so new object will be created. and comparing it with s1 (using'==') give false.
Same for S3. But for S3 it wont create new object as "anil" is already there in constant pool.
so will return the reference of S1. So it gives true.
Study the following link
Study this
Case 1: String with Capital First Letter.
> String s1 = new String("Ajay")
String s2 = s1.toUpperCase()
String s3 = s1.toLowerCase()
System.out.println s1 == s2
System.out.println s1 == s3
false
false
Case 2: String with Small First Letter.
> String s1 = new String("ajay")
String s2 = s1.toUpperCase()
String s3 = s1.toLowerCase()
System.out.println s1 == s2
System.out.println s1 == s3
false
true
in Case 1, since the string has capital letter, converting to lowercase will yield a new object hence a new reference for it while in Case 2 small first letter after converting to lowercase will still point to the same object because the original object was same hence creating two references for the same object.
You can see the output from the Groovy Shell pretty clear.
If you look at the toLowerCase() method in String class.
It calls toLowerCase(Locale locale)
toLowerCase(Locale locale) inturn uses Character.toLowerCase(c)
Character.toLowerCase(c) in Character class has this comment -
#param ch the character to be converted.
#return the lowercase equivalent of the character, if any;
otherwise, the character itself.