This week's giveaway is in the Android forum.
We're giving away four copies of Android Security Essentials Live Lessons and have Godfrey Nolan on-line!
See this thread for details.
The moose likes Beginning Java and the fly likes == and HashCode Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "== and HashCode" Watch "== and HashCode" New topic
Author

== and HashCode

adithya narayan
Ranch Hand

Joined: Jan 05, 2009
Posts: 79

Hi,

I was going through the '==' operator. If used for two primitives with same values it will return true else false. For object references pointing to same objects i.e.


will return true.

I was working on wrapper classes.


will return true since, for integers if values are between -127 and 128 it will be true else false.

1)Are we still creating two Integer objects over here or creating one and assigning both the reference to the same ? If we are craeting two objects then how does JVM have this mechanism to equalise two different references ?

2)Can anyone tell the behavior for other wrapper classes (the range for which the JVM will try to save memory as in the case for Integer ) or it isn't in place ?.


3)Doesn't the '==' work for String objects considering String pooling literals ?

For example,


Ideally, string1 and string4 will refer to a single object in memory right (as "abc" is present in the pool)?Am i right ?

But after i run it returns false !! whereas returns true !

Can anyone please explain this behavior ?

Thanks,
Adithya.

Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3599
    
  14

The == operator always compares objects for identity. Meaning it will only return true if two references point to the exact same object.

Byte, Short, Character and Integer put their instances in their own respective pools, in the same way String does; with the exception that String does it with every literal, while the former classes only do so for byte-sized values.
Note that the range for Character is limited to 0 - 127, because its values are considered unsigned.

So if you assign the same byte-sized literal to two different wrapper variables, they will point to the same object. I don't think Java does any of this for the decimal classes (Float and Double).

So yes, you can use == to compare wrapper instances that were created this way. You can also use == to compare Strings formed from literals. Personally, I still consider it bad practice. Always use equals() instead.

hashcode() returns the same value for the two different Strings, because they have the same value. You will find that equals() returns true.
== returns false for those Strings, because the references point to two different objects, even though their values are the same. don't use new String() to create Strings.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19654
    
  18

Stephan van Hulst wrote:Byte, Short, Character and Integer put their instances in their own respective pools, in the same way String does; with the exception that String does it with every literal, while the former classes only do so for byte-sized values.

The same goes for Long too. But even though short, int and long have a wider range than byte, the bounds are still -128 and 127. For Integer you can increase that using system property "java.lang.Integer.IntegerCache.high". This is not mentioned in the Javadoc because it was added in one of the later updates of Java 6. I can't remember which one though, but you shouldn't count on it. It should be used as a performance improvement only. Just like you should .equals for String comparison, you should also use .equals for wrapper instance comparison.

So if you assign the same byte-sized literal to two different wrapper variables, they will point to the same object. I don't think Java does any of this for the decimal classes (Float and Double).

Correct. It wouldn't make much sense for these classes, as there are so many possible values. The only values I could imagine would be 0.0, 1.0, NaN and positive and negative infinity.

So yes, you can use == to compare wrapper instances that were created this way. You can also use == to compare Strings formed from literals. Personally, I still consider it bad practice. Always use equals() instead.



SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
adithya narayan
Ranch Hand

Joined: Jan 05, 2009
Posts: 79

Stephan van Hulst wrote :
So yes, you can use == to compare wrapper instances that were created this way. You can also use == to compare Strings formed from literals. Personally, I still consider it bad practice. Always use equals() instead.


I wanted to know whether two references were referring to the same object and as far as i know it can be accomplished using the '==' operator.
'equals()' method will help me know whether the objects are 'meaningfully equivalent' right ?

== returns false for those Strings, because the references point to two different objects, even though their values are the same


Do you mean the following will always be false ?


If it will always be false then can you please give clarification for the following:
1)When string1 was created with the literal 'abc' , the value went into the string pool (assuming previously the pool is empty).
2)When string2 was created with the same literal 'abc' , the value was found in the pool and assigned the reference to the same object.
Hence, i was thinking that the '==' operator should have worked in the above case.Please correct my understanding if i am wrong.
3)What should be the behavior for the following and why:



hashcode() returns the same value for the two different Strings, because they have the same value. You will find that equals() returns true.

1)Can you please tell the difference between hashcode() and eqauls() method ?

don't use new String() to create Strings.

1)Why shouldn't the new String() be used ?


Thanks,
Adithya.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19654
    
  18

adithya narayan wrote:Do you mean the following will always be false ?

Yes.

If it will always be false then can you please give clarification for the following:
1)When string1 was created with the literal 'abc' , the value went into the string pool (assuming previously the pool is empty).
2)When string2 was created with the same literal 'abc' , the value was found in the pool and assigned the reference to the same object.
Hence, i was thinking that the '==' operator should have worked in the above case.Please correct my understanding if i am wrong.

If you write then yes, string1 == string2. You however are creating two copies of the String literal. Those are different objects. Remember, every time you use "new" you create a new object. In your example string1 and string2 are both referencing new, different objects.

3)What should be the behavior for the following and why:

Still false, because string1 is still referencing a new object, not the String literal.

hashcode() returns the same value for the two different Strings, because they have the same value. You will find that equals() returns true.

1)Can you please tell the difference between hashcode() and eqauls() method ?

Please read the Javadoc page of java.lang.Object. It explains it all.

don't use new String() to create Strings.

1)Why shouldn't the new String() be used ?

Stephan is not 100% accurate here. You should hardly ever use new String(String) and never use new String(); the other constructors can be used as needed. See this thread for more information on why not to use new String(String), and the rare occasion where it should be used.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38033
    
  22
adithya narayan wrote: . . . 1)Can you please tell the difference between hashcode() and eqauls() method ?
Does the API documentation for Object help? That should be the first place you look.
. . . Why shouldn't the new String() be used ? . . .
See whether this recent thread helps. Mike Simmons points out there is very rarely a real use for new String("abc")
Jesper de Jong
Java Cowboy
Saloon Keeper

Joined: Aug 16, 2005
Posts: 14074
    
  16

Campbell Ritchie wrote:See whether this recent thread helps. Mike Simmons points out there is very rarely a real use for new String("abc")

As you can see in that thread, there is never a reason to use new String("abc") - that is, calling the String constructor with a string literal as the argument. There is a situation where you'd want to call the String constructor with another String object - but never with a literal.

Java Beginners FAQ - JavaRanch SCJP FAQ - The Java Tutorial - Java SE 7 API documentation
Scala Notes - My blog about Scala
Stephan van Hulst
Bartender

Joined: Sep 20, 2010
Posts: 3599
    
  14

I have also used the constructor that takes a byte array and an encoding a few times, but I can't think of a better alternative for that one right now. Maybe String has a factory method for that one? I should take a look.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38033
    
  22
You're right Jesper; I wrote that imprecisely.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: == and HashCode
 
Similar Threads
Creation of Ineger Wrapper Object
Immutable wrapper classes
Integer's == and !=
comparison doubt - K&B book
Wrapper