hashCode as object ref in JDK 8 [duplicate] - java

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
From what i know, jdk 8 now is assigning as hashCode the memory address of the object.
And, obj1 = obj2 returns true iff the obj1 is obj2, i.e., they're sitting at the same memory location.
However, the following code executes the "else" part-- not the "then" part of the if-stat which is what i expect:
String h1 = "heya";
String h2 = new String ("heya");
System.out.println("hashCodes "+h1.hashCode()+" "+h2.hashCode());
if (h1 == h2)
System.out.println("yeah - the same ");
else System.out.println("nope-- difft objects ");
What am i missing here?
TIA.

h1 and h2 are not sitting in the same memory location. You are calling a new String("heya") so the JVM will create a new instance of String. Therefore, h1 == h2 is false. The hasCode is the same because it is based on the char composing the String.
Using equals method instead of == will return true.

The String class overrides hashCode().

Related

String comparison in Java 6 vs Java 7 [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 7 years ago.
I know that Strings in Java should be compared using .equals() and not using == operator.
But in the given below code there is a primaryObserverId which has a value of ""
The given below if condition runs fine on Java 6 but fails on Java 7
String primaryObserverId = request.getParameter("primary_observer_id");
if(primaryObserverId == null || primaryObserverId=="")
primaryObserverId = RoleMap.getUserIdForThisSession(session.getId());
Need to know why this code was working on Java 6 and not on Java 7.
I know how the concept of String Pool works for string literals in java , just want to know the reason this abrupt behavior.
Can using different version of GlassFish may cause any issue as I am using GlassFish-2.1 with Java 6 and GlassFish-4.1 with Java 7
All string literals in java are placed in a special area of the heap as they are required. So if you have a variable that is initialised to an empty string, this string is added to the heap. If you have another variable that is initialised to an empty string then it will contain a reference to the empty string already on the heap rather than creating a new one. So it seems your problem is that when you run your application in java 6 for some reason an empty string is on the heap at that point so you can check that the two strings are exactly the same object. However when run in java 7 there is no empty string on the heap so the two string must be completely different objects.
See this article for a more complete explanation.
== compares the address in memory while equals() compares if 2 objects are meaningfully equivalent, so in your case it makes more sense to user the equals() method as the Servlet creates the String not using the pool, so they are not == but they are meaningfully equivalent, therefore equals.
String primaryObserverId = request.getParameter("primary_observer_id");
if(primaryObserverId == null || "".equals(primaryObserverId)){
primaryObserverId = RoleMap.getUserIdForThisSession(session.getId());
}

Java test String Handling [duplicate]

This question already has answers here:
Comparing strings with == which are declared final in Java
(6 answers)
Closed 7 years ago.
I was doing some java tests to practice and I came across a question that I don't understand. I created a small program to test it:
The question was to say what would be the output of System.out.println(ab==abc);
I answered 'true' thinking that String literals are not objects, so the can be seen as a kind of primitive type so the comparation == would compare the values and nothing to do with references. But actually the answer in "false";
Then I did this test and I even print the outputs and as you can see ab and abc are exactly the same, however the comparation is returning false , but if I do the comparation directly without doing any concatenation (as I did at the end of the program) the comparation is returning true. So it seems clear the reason has to be with the concatenation, I know that Strings are inmutable so when concatenating then we are getting another String literal with exactly same value.
Can someone please explain me who't going on here?
For those telling me that String literals are objects, why then this code returns true?
String p="meowdeal";
String o="meowdeal";
System.out.println(o == p);
//output true
Of course I would understand that this code
String o=new String("meowdeal");
String p=new String("meowdeal");
System.out.println(o==p);
returns false because in that case they are really objects but not when they are String literal, am I right?
Thank you for your time
public static void main(String ads[] ){
String a="meow";
String ab=a+"deal";
String abc="meowdeal";
System.out.println(a);
System.out.println(ab);
System.out.println(abc);
System.out.println(ab == abc);
//output
//meow
//meowdeal
//meowdeal
//false
String p="meowdeal";
String o="meowdeal";
System.out.println(o == p);
//output
//true
}
ab and abc are objects so .equals() is used to see if they have the same contents and == is used to see if they are the same object.
The last test is only true due to a compile optimization known as string interning
(Your second comment below is correct)
In Java you should compare Strings with .equals(String s) because the '==' returns only true if it's the exact same String in the memory and doesn't compare if the content is the same. In your first example you've got two different strings in your memory. In the second, java saw, that these would be the same and allocated only space for one string and your p and o are only a reference to the same object.
String literals are Objects. User equals method instead of == operator.
Just to explain what happen here,
String p="meowdeal"; //creates "meowdeal" in heap
String o="meowdeal"; // o also refer to same object in heap.
This is called pooling of String. Since both refer to same memory location == operator returns true.

Can anyone please explain why output of the following is such? [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 8 years ago.
String str1 = "abc:5";
String str2 = "abc:" + str1.length();
String str3 = "abc:" + 5;
System.out.println(str1==str2);
System.out.println(str1==str3);
Output of the program is :
false
true
But I don't understand why?
== operator will compare reference only
.equals() will compare the values.
in your case
str1==str2 // compares the two references, which are different.
had it been, str1.equals(str2), it would have compared the values, which will return true
The “==” operator
In Java, when the “==” operator is used to compare 2 objects, it checks to see if the objects refer to the same place in memory. In other words, it checks to see if the 2 object names are basically references to the same memory location.The “==” operator compares the objects’ location(s) in memory
The “equals” method
The Java String class actually overrides the default equals() implementation in the Object class – and it overrides the method so that it checks only the values of the strings, not their locations in memory.
Here str1 = "abc:5"; is located in constant pool of string and str2 is concatenated with 2 different object with new operator. So both str1 and str2 are referring to different object. That's the reason it is showing false.
The == operator is used for only reference variables in java. For example if you are comparing characters a1 and a2 you can use the == operator because the char type is highlighted in most IDEs in Java. To check if two Strings are equal to each other you can use .equals()or .equalsIgnoreCase() to compare the Strings. This is because Strings are objects, not primitives, and require their own method in the class to test if Strings are the same.
For the first System.out.println(); statement, you would use System.out.println(str1.equals(str2)); or System.out.println(str1.equalsIgnoreCase(str2));.
For the second System.out.println(); statement, you would use System.out.println(str1.equals(str3)); or System.out.println(str1.equalsIgnoreCase(str3));.

String s=new String("Rohit"); Does this statement creates an object in heap only or it makes an entry in string pool as well? [duplicate]

This question already has answers here:
Difference between string object and string literal [duplicate]
(13 answers)
What is the difference between "text" and new String("text")?
(13 answers)
Closed 8 years ago.
I attended interview and i was asked this question.
String s=new String("Rohit");
Does this statement creates an object in heap only or it makes an entry in string pool as well?
I answered it does not make entry in pool. I think with .intern() it would make entry in string pool. Interviewer's thought was opposite.
Could you please guide me if i was wrong or interviewer?
Thanks in Advance.
EDIT:
String s1=new String("Rohit");
String s2="Rohit";
String s3=new String("Rohit").intern();
System.out.println(" "+(s2==s3)+" "+(s1==s2)+" "+(s1==s3)+" "+(s2==s3));
results as :true false false true
This makes me to think that without using intern() with new, there is no entry in pool for this object
Several things wrong with what you say he said:
First, doing new String always returns a new string, and never one that is interned.
Second, while it is true that the presence of the string literal "Rohit" might cause a String of that value to be "interned" (what is erroneously referred to as placing in the "string pool" or "string constant pool"), that would be done (if it was done) when the class was loaded, not when the statement was executed.
Third, since there can only ever be one copy of a String with a given pattern in the interned string table, even loading the class is not guaranteed to add a new entry, since one might already be there.
Of course, as is often the case, there may have been some misunderstanding on the part of one or both of you, or the question (or your answer) may have been poorly/unclearly worded.
I agree with #Hot Licks, but the behaviour of when a String literal is loaded changed in Java 7 AFAICS.
String literals are loaded when the class is loaded in Java 6 but in Java 7 they changed this to be when the first line which uses the string is executed. You can detect this by looking at the String returned by String.intern(); The first time it is called for a String it will return the same object, however when called again with an equals() String it will return the previous object.
StringBuilder sb = new StringBuilder("Hell");
sb.append("o");
String s = sb.toString();
String si = s.intern(); /* same string if not loaded. */
String s2 = "Hello";
System.out.println( System.getProperty("java.version")+" " + (s == si) + " "+(s2 == s));
prints
1.6.0_45 false false
as you expect, but in Java 7+
1.7.0_45 true true
If s2 is loaded first, the intern() string si will be the same as it, and thus different to s However, if s2 is loaded after, all the Strings use the same object.

condition == between string and constant [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I compare strings in Java?
Someone can tell me why this condition
if (lista.getString(0)=="username")
do not return true? I've used to try
if (lista.getString(0)==lista.getString(0))
and dont work, and i have understand that is a language problem.
== tests for reference equality.
.equals tests for value equality.
Threfore you should use:
if (lista.getString(0).equals("username"))
See How do I compare strings in Java?
For String comparison always use equals().
if (lista.getString(0).equals("username"))
Using == , you will end up comparing references, not values.
A simple snippet to clarify further:
String s1 = "Hello";
String s2 = new String(s1);
System.out.println(s1.equals(s2)); // true because values are same
System.out.println((s1 == s2)); // false because they are different objects
From Java Techniques
Since Strings are objects, the equals(Object) method will return true if two Strings have
the same objects. The == operator will only be true if two String references point to the
same underlying String object. Hence two Strings representing the same content will be
equal when tested by the equals(Object) method, but will only be equal when tested with
the == operator if they are actually the same object.
Use
if (lista.getString(0).equals("username"))
The correct way to compare objects is with,
object1.equals(object2)
And String is an object in Java, so it implies same for String too
s1.equals(s2)
eg :
if (lista.getString(0).equals("username"))

Categories