Java : Boxing and using == [duplicate] - java

This question already has answers here:
Why Integer class caching values in the range -128 to 127?
(5 answers)
Closed 6 years ago.
Lets say i have something like
int a = 100;
int b = 100;
Integer c = (Integer) a;
Integer d = (Integer) b;
c == d results to true. Does that mean objects c and d point to the same Object in memory?
Can any one shed light here?
Do we create 2 objects c and d here? Are they different objects or same? == tells me that they are same objects.
I also read somewhere that casting doesn't create new objects. It's just a way of representing the same object. That makes sense if I am trying to cast lets say an Object to a Integer.
But what about this case, where there is no object in picture before (all we had is primitives) and we are trying to create Object c and d here?

Autoboxing works without casting. The reason you're seeing reference equality is because autoboxing internally calls Integer.valueOf() which caches certain values:
This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.

Related

Access a Java Hashtable with int and byte key [duplicate]

This question already has answers here:
What happens if two different objects have the same hashcode?
(5 answers)
Closed 4 years ago.
I have a Hashtable to find objects by number. Let's assume I do
Hashtable<Integer, MyClass> table = ...
table.put(10, myObject);
and query this with a byte or Byte object that also has value 10, then I get no result.
Byte b = new Byte(10);
table.get(b); // -> null
table.get((int)b); // -> myObject
table.get(10); // -> myObject
table.get((byte)10); // -> null
Byte and Integer objects are different, I know. But it compiles and both have the same hashcode, namely the value 10. Shouldn't both find the object?
The byte value on one of my cases is unchangeable. I can cast it to int but I would like to understand what's going on here.
Edit: Let me make clearer what my problem was. I thought as this hashlist has an Integer as key type, either I should get an error if I use something different that an int (which is converted into integer) or another number type is automatically converted into int. This made me wonder.
It is not enough they got same hashCode, when you call get method, the key should also equals the one you put before.
Byte and Integer are different classes, so they are not equal with each other, that's why you got null with table.get(b) or table.get((byte)10).

Java Hashset Storing items based on value and not hashcode [duplicate]

This question already has answers here:
Hashcode of an int
(4 answers)
Closed 4 years ago.
HashSet hs = new HashSet();
hs.add(1000);
hs.add(new Integer(1000));
System.out.println(hs);
The above code prints [1000] but I have used the new operator which shall create a new object in memory and hence the hash code must be different ,so should it not have two values in hashset?
I have used the new operator which shall create a new object in memory and hence the hash code must be different
That assumption is not correct. The default hashCode implementation returns a different hash for different instances, but that is not a requirement. In many cases you actually want different instances to return the same hashCode (calculated from instance members) to be able to compare instances for equality.
From the documentation of Integer hashCode:
Returns: a hash code value for this object, equal to the primitive int value represented by this Integer object.
If you actually want a map that doesn't use equals/hashCode, take a look at the IdentityHashMap class.
To understand it better lets make a small test, lets find the hashCode of this cases :
int i1 = 1000;
Integer i2 = 1000;
Integer i3 = new Integer(1000);
System.out.println(Integer.valueOf(i1).hashCode());
System.out.println(i2.hashCode());
System.out.println(i3.hashCode());
All the cases return the same hashCode.
Outputs
1000
1000
1000
For that you get one value in the Set and not two like you expected.
Integer's hashcode() method returns hash code value for the object which is equal to the internally stored primitive int value, which in your case is 1000.

About Java memory management [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Integer wrapper objects share the same instances only within the value 127?
I have a question about the memory management in Java.
When I try the following code:
Integer a = 1;
Integer b = 1;
System.out.println(a==b); // this gives "true"
However,
Integer a = 256;
Integer b = 256;
System.out.println(a==b); //this gives "false"
Why?
Thanks very much.
That is because "autoboxing" uses Integer.valueOf, and Integer.valueOf keeps a cache of Integer objects for small integer values. Here's what the JLS says:
"If the value p being boxed is true, false, a byte, or a char in the range \u0000 to \u007f, or an int or short number between -128 and 127 (inclusive), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2." JLS 5.1.7.
When you use the == operator to compare a pair of Integer objects, it is actually comparing the object references. So your get true if boxing gave you the same cached Integer object, and false if it didn't. Note that the JLS guarantees this behaviour for the ranges stated, but it also permits an implementation of the valueOf method to cache a wider range of values.
The bottom line is that you should use equals(Object) to compare Integer objects ... unless you are really trying to test if they are the same object.
According to what I read, "Integer" should create an "object" in the heap, thus the two objects should be the same.
If your code explicitly does a new Integer(...), it is guaranteed to create a new Integer object. However, autoboxing uses Integer.valueOf(...), and that is where the caching behaviour is implemented.
You shouldn't use reference equality (==) for objects. It's printing true in your first example because the first 128 Integer objects are cached by the Integer class. Use .equals()
When the values greater than range of data representation, they are different object because they are wrapped. You are now coparing like object ids.
You are comparing objects' addresses

using new(Integer) versus an int

In my Java class, the professor uses something like:
integerBox.add(new Integer(10));
Is this the same as just doing:
integerBox.add(10);
?
I've googled a bit but can't find out one way or the other, and the prof was vague.
The closest explanation I can find is this:
An int is a number; an Integer is a pointer that can reference an
object that contains a number.
Basically, Java collection classes like Vector, ArrayList, HashMap, etc. don't take primitive types, like int.
In the olden days (pre-Java 5), you could not do this:
List myList = new ArrayList();
myList.add(10);
You would have to do this:
List myList = new ArrayList();
myList.add(new Integer(10));
This is because 10 is just an int by itself. Integer is a class, that wraps the int primitive, and making a new Integer() means you're really making an object of type Integer. Before autoboxing came around, you could not mix Integer and int like you do here.
So the takeaway is:
integerBox.add(10) and integerBox.add(new Integer(10)) will result in an Integer being added to integerBox, but that's only because integerBox.add(10) transparently creates the Integer for you. Both ways may not necessarily create the Integer the same way, as one is explicitly being created with new Integer, whereas autoboxing will use Integer.valueOf(). I am going by the assumption the tutorial makes that integerBox is some type of collection (which takes objects, and not primitives).
But in this light:
int myInt = 10;
Integer myInteger = new Integer(10);
One is a primitive, the other is an object of type Integer.
integerBox.add(10);
is equivalent to
integerBox.add(Integer.valueOf(10));
So it may return the cached Integer instance.
Read Java Specialist 191 for various way of setting autoboxing cache size.
See also: cache options
In this case, yes. I'm assuming that integerBox is a collection of objects - you can only store objects within integerBox. This means that you cannot have a primitive value, such as an int, within the collection.
After Java 5 was released, however, there came about something called autoboxing. Autoboxing is the process of automatically converting a primitive value to an object. This is done through one of the wrapper classes - Integer, Double, Character, etc (all named with a capital letter and a name pertaining to the primitive value that they represent).
When you added int 10 to the collection(ArrayList, most likely), the Java VIrtual Machine transformed it into an object of type Integer behind the scenes.

== operator for primitive data types [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How Does the toString(), ==, equals() object methods work differently or similarly on reference and primitive types?
I am trying to understand the difference between == and equals to operator in Java.
e.g. == will check if it is the same object while equals will compare the value of the object ... Then why do we use == for comparing primitive data types like int.
Because if I have
int i =7; //and
int j = 6.
They are not the same object and not the same memory address in stack. Or does the == behaves differently for primitives comparison.??
Actually, == behaves identically for all variables: it tests whether the values of those variables are equal. In the case of Object obj, obj is a reference to an object. Since == tests whether two object references have the same value, it is testing whether they refer to the identical object (i.e., that the references are equal).
== intuitively work differently on primitive types. Its just that way in the language.
If you think about it in C++ terms, references are pointers and == does pointer comparison.
int* myPtr1 = new int(5);
int* myPtr2 = new int(6);
myPtr1 == myPtr2;

Categories

Resources