Using '==' instead of .equals for Java strings [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What makes reference comparison (==) work for some strings in Java?
I know this has been asked before, but in spite of recommendations to use .equals() instead of the == comparison operator, I found that == works all the time:
String s1 = "Hello";
String s2 = "Hello";
System.out.println(s1 == s2); // true
Can anyone give me an example of the == operator failing?

This is because you're lucky. The == operator in Java checks for reference equality: it returns true if the pointers are the same. It does not check for contents equality. Identical strings found at compile-time are collapsed into a single String instance, so it works with String literals, but not with strings generated at runtime.
For instance, "Foo" == "Foo" might work, but "Foo" == new String("Foo") won't, because new String("Foo") creates a new String instance, and breaks any possible pointer equality.
More importantly, most Strings you deal with in a real-world program are runtime-generated. User input in text boxes is runtime-generated. Messages received through a socket are runtime-generated. Stuff read from a file is runtime-generated. So it's very important that you use the equals method, and not the == operator, if you want to check for contents equality.

Can anyone give me an example of the == operator failing?
Example 1:
String s1 = new String("Hello");
String s2 = new String("Hello");
System.out.println(s1 == s2); // false
Example 2:
Integer a=1000,b=1000;
System.out.println(a == b); // false

When you do this, you are actually creating string literals:
String s1 = "Hello";
String s2 = "Hello";
The compiler finds identical string literals and then optimizes by keeping one instance in the heap and making all the variables in the stack point to it. So doing an == will return true because they point to the same memory address.
When you do this, you are creating string objects:
String s1 = new String("Hello");
String s2 = new String("Hello");
The instantiation will create unique space on the heap for each of these and the stack variables will point to those separate locations. Thus, these will be equal using .equals() because their values are the same, but they will not be equal using == because they are different objects in the heap memory space.

Seasoned Java developers rarely if ever use new String(String), but the problem arises in other cases as well. For example:
String hello = "Hello"
String hell = hello.substring(0, 4);
System.err.println("Hell" == hell); // should print "false".
(Most String instances in a real-world applications are formed either by taking a substring of some other String, or by constructing it from an array of characters. Very few applications will only use String instances created as literals.)

Related

questions about java strings [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 4 years ago.
(true or false)Suppose String objects b and c contain the same sequence of characters. Then b == c is true.
public static void main(String[] args) {
String a = "abc";
String b = "abc";
System.out.println(a == b);
System.out.println(a.equals(b));
}
The result is true, but the answer to the question is false. I was wondering why.
public static void main(String[] args) {
String a = new String("abc");
String b = new String("abc");
System.out.println(a.equals(b));
System.out.println(a == b);
}
Prints true, then false. So two strings with the same sequence of characters do have to equal each other, but can either == each other or not.
Obviously, a == a under all circumstances, and a is a String containing the same sequence of characters as a.
But in the example above, we're creating two different instances, which just happen to contain the same sequence of characters. Hence a != b.
So what's happening in your example? String interning.
Any string literals are allocated in a special pool by the compiler, and any duplicate literals share the same reference. So even though the literal is defined twice, as far as the compiler's concerned, they're the same instance.
The reason your test results in true is a very weird thing that the JVM likes to do. Because you've defined two String literals, the JVM will just decide to store one of those values, and have both a and b refer to the same string. This is why doing == comparison results in true.
As someone else stated, doing String b = new String("abc"); will force a new String literal to be made, which would be a separate block of memory. Thus == comparison would result in false.

How new String() and normal String created ? String class in java (Confusion) [duplicate]

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?

Is string Object Created in Heap if we use new String("abcd") [duplicate]

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.

Checking a number in String Variable [duplicate]

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
}

Why == is different for Integer and String?

main(){
Integer i1 = 500;
Integer i2 = 500;
System.out.println(i1 == i2); // O/P is "**false**"
String s1 = "Hello";
String s2 = "Hello";
System.out.println(s1 == s2); // O/P is "**true**"
} // End of main.
I am not able to figure out why the output is different. As far as I know s1, s2 will point to the same object on the heap. So their reference address are same. Similarly I think Integer is also the same. But it is not. Why is it different?
It has been already answered here: java: Integer equals vs. ==
Taken from this post: The JVM is caching Integer values. == only works for numbers between -128 and 127. So it doesn't work with 500 in your example.
Use string1.equals(string2); //Used for String values
Instead of using string1 == string2; //Used for integer values
Hope this helps.
The answer in this question should help explain it:
How to properly compare two Integers in Java?
Pretty much you answered your own question. The "==" is not only comparing the reference points in strings, but it seems to do the same thing with integers.
The way you specified "Hello" does no heap allocation. Instead, "Hello" as a static compile-time constant will be outsourced to the specific section of the executable and referenced. Thus, both references will point to the same address.
So there is Java String Pool and here s1 and s2 actually the same links.
In case of Integers, there is also pool but it exists only for Integers -127 till 128
So if you have
Integer i1 = 100;
Integer i2 = 100;
Then i1==i2 will be true
"==" always compare the memory location or object references of the values.
equals method always compare the values.but equals also indirectly uses the "==" operator to compare the values. Integer uses Integer cache to store the values from -128 to +127.If == operator is used to check for any values between -128 to 127 then it returns true. for other than these values it returns false .
In string, if string is initialized like this
String s1="abc"
String s2="abc"
String s1 and s2 are pointing the same location in memory or String pool.
if string is initialized like this
String s1=new String("abc");
String s2=new String("abc");
String s1 is pointing the new location in which it contains String "abc"
String s2 is pointing the new location in which it contains String "abc" but s1's location is different from s2's location.In that situation equals method is useful for string comparison.
Refer the link for some additional info

Categories

Resources