Reputation: 21
I have the following piece of Java code using HashMap and generics:
import java.util.*;
import java.io.*;
public class Map{
static HashMap<Integer, Integer> imap;
static HashMap<Integer, Thing> tmap;
public static void main(String[] args){
imap = new HashMap<Integer, Integer>();
imap.put(0,0);
Integer i = imap.get(0);
i = i + 1;
System.out.println(imap.get(0));
tmap = new HashMap<Integer, Thing>();
tmap.put(0,new Thing(0));
Thing t = tmap.get(0);
t.a = t.a + 1;
System.out.println(tmap.get(0).a);
}
}
class Thing{
public int a;
public Thing(int n){
this.a = n;
}
}
which prints out the following:
0
1
I would expect it to print either both ones (if I were modifying the reference) or both zeros (if I were modifying the values). So why is the behaviour different for a map from integer to integer than from integer to thing?
Upvotes: 0
Views: 923
Reputation: 2092
Answering the second part of the question ("But then why does it print 1 on the second print statement?"), it's because the lines ...
Thing t = tmap.get(0);
t.a = t.a + 1;
... get you a reference to the object located within the hashmap at a given location, and then modify a member variable of the referenced object. The println statement then retrieves another reference to that same object with the now-modified member variable.
Upvotes: 0
Reputation: 9427
By doing i=i+1 you are incrementing not the value stored in the java.lang.Integer contained in the map.
Upvotes: 1
Reputation: 81
It's because you're auto-unboxing the Integer value when you grab it from the first map (by assigning an Integer to an int). At that point you're not using an Integer reference, you're using an int primitive, with no relationship to the Integer reference held in the map.
As java Integers are immutable, there's really no way to do what you're trying to demonstrate here. There is no way to modify the internal primitive int held by the Integer reference in the map. You'd have to .put a new Integer to change the value held at key 0.
Upvotes: 0
Reputation: 3294
I think i = i + 1; will not be updated on the object because the get will be a copy by value as you assigning to a primitive. The primitive update will therefore not reflect in the map as you don't hold a reference. With the next example in Thing you are directly assigning back to the public primitive of the Thing, so again by value - but you update the public int.
Upvotes: 0
Reputation: 806
Java's integer types are not mutable, so your first example takes the value from the map, then replaces the local variable with the new value. However, the second example gets a reference to the Thing instance from the map.
Upvotes: 5