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.
Related
String str1 = "The rumour is that the neighbours displayed good behaviour by labouring to help Mike because he is favoured.";
str1.replaceAll("our", "or");
System.out.println(str1);
Method replaceAll returns a new string where each occurrence of the matching substring is replaced with the replacement string.
Your code doesn't work because String is immutable. So, str1.replaceAll("our", "or"); doesn't change str1.
Try this code:
String str1 = "I am trying to replace the pattern.";
String str2 = str1.replaceAll("replace", "change");
System.out.println(str2);
If you don't what str2, try this code:
String str1 = "I am trying to replace the pattern.";
System.out.println(str1.replaceAll("replace", "change"));
And read about Immutability of Strings in Java.
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 is a very basic question regarding String.
String str1 = "abc";
String str2 = "abc";
System.out.println("out put " + str1 == str2);
I was shocked when I executed the program. I got false.
According to me, string literals are shared between the String references if another string wants to point to the same String literal. JVM will check it in String pool first and if it is not there then it will create one and give the reference, otherwise it will be shared between multiple String references like in this case (according to me).
So if I go by my theory then it should have been returning true as both the String reference point to same String literal.
You need to do the following to check it correctly:-
System.out.println("out put " + (str1 == str2));
This will give you true as expected.
Your statement does "out put" + str1 and then tries to equate it with str2
You're right about the String behaviour. But, you forgot about operator precedence. First addition is executed, later equality.
So, in your case, firstly "out put " + str1 is executed, which gives "out put abc". Later this is compared to str2, which gives false.
You meant "out put " + (str1 == str2), which indeed gives true.
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");
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 9 years ago.
I am getting a value as 9999912499 from the database.
I have separated it in two parts 99999 and 12499 using substring.
Now I want to check whether if the 1st string is equal to 99999 then i do some processing otherwise something other processing.
But controls never gets in to the if loop
Following is a snapshot:
String strPscId = Long.toString(pscID);
String convPscID = strPscId.substring(5, strPscId.length());
String checkNine = strPscId.substring(0,5);
BigDecimal jpaIdObj = jeuParam.getJpaIdObj();
Long mod_id = modele.getModId();
log.info("outstrPscId == " +strPscId);
log.info("outconvPscID == " +convPscID);
log.info("outcheckNine == " +checkNine);
log.info("outjpaIdObj == " +jpaIdObj);
log.info("outmod_id == " +mod_id);
if(checkNine == "99999") { <method-call> }
else { <another - method - call> }
For some reason, the people that make java decided that == shouldn't be used to compare Strings, so you have to use
checkNine.equals("99999");
Look at the following code:
String str1 = "abc";
String str2 = str1;
In the first line, a new string is created and stored in your computer's memory. str1 itself is not that string, but a reference to that string. In the second line, str2 is set to equal str1. str2 is, like str1, only a reference to a place in memory. However, rather than creating an entirely new string, str2 is a reference to the same place in memory that str1 is a reference to. == checks if the references are the same, but .equals() checks if the each character in a string is the same as the corresponding character in the other string.
boolean bool1 = (str1 == str2);
boolean bool2 = str1.equals(str2);
If this code were added to the code above that, both bool1 and bool2 would be true.
String str1 = "abc";
String str2 = new String(str1);
boolean bool1 = (str1 == str2);
boolean bool2 = str1.equals(str2);
In this case bool2 is still true, but bool1 is false. This is because str2 isn't set to equal str1, so it isn't a reference to the same place in memory that str1 is a reference to. Instead, new String(str1) creates an entirely new string that has the value of str1. str1 and str2 are references to two different places in memory. They contain the same value, but are fundamentally different in that they are stored in two different places, and therefore are two different things.
If I replaced new String(str1) with "abc" or str1, bool1 would be true, because without the key word new, the JVM only creates a new string to store in memory if absolutely necessary. new forces the JVM to create an entirely new string, whether or not any place in memory already has the same value as the new string being created.
.equals() is slow but generally more useful than ==, which is far faster but often does not always give the desired result. There are many times when == can be used with the same result as .equals(), but it can be difficult to tell when those times are. Unless you a knowledgeable programmer making something where speed is important, I would suggest that you always use .equals().
You need use equals method, rather than == to compare strings.
Change from
if(checkNine == "99999")
to
if(checkNine.equals("99999"))
The == operator is used to compare the content of two variables. This works as expected when using primitive types (or even wrapper classes because of auto-boxing). However, when we are using == with a reference to an object (e.g., checkNine), the content is the reference to the object but not the value of the object. This is where equals() method is used.
if("99999".equals(checkNine)){
<method-call>
}
else {
<another - method - call>
}
if(checkNine.equals( "99999")) {
<method-call>
}
else {
<another - method - call>
}
if (strPscId.startsWith("99999"))
{
bla bla
}
else
{
sth else than bla bla
}