I am having a problem copying a HashMap A to HashMap B. B is always same as A. My idea is making a small tile game using HashMaps only.
Map<Point,Tile> A = new HashMap<Point,Tile>();
HashMap has 2 things. A point(key) and a tile object, which is another class I have made. Tile takes in two integers and a string. ( new Tile(x,y,string)). First two integers defines the point x and y and the string tells if its "OFF" or "ON".
What I do first is populate HashMap A with 2*2 elements.
for(int i=0; i<2;i++){
for(int j=0; j<2;j++){
Tile t = new Tile(i, j, "OFF");
A.put(new Point(i,j), t);
}
}
Then I copy HashMap A to HashMap B by adding A in constructor. My idea is so I can go back to default HashMap A by using HashMap B in the constructor(See later)
Map<Point,Tile> B = new HashMap<Point,Tile>(A);
Then I change tile (1,1) to "ON"
Tile t2 = A.get(new Point(1,1));
t2.setS("ON");
One of my tiles is "ON" now. Now I want to reset the board back to original(After the population stage). I clear HashMap A and make a new HashMap with HashMap B as the constructor.
A.clear();
A = new HashMap<Point,Tile>(B);
However, when I changed tile (1,1) to ON on HashMap A , it updated HashMap B as well. I thought making a new HashMap with a constructor will make a new copy of it, but doesn't seem to work.
The strange thing is that
Map<Point,String> A = new HashMap<Point,String>();
would work but not
Map<Point,Tile> A = new HashMap<Point,Tile>();
I want to somehow get the Original contents of HashMap A without me trying to loop over the elements again.
Here's my main class code
package main;
import java.awt.Point;
import java.util.HashMap;
import java.util.Map;
import model.Tile;
public class Test {
public static void main(String[] args) {
//list1
Map<Point,Tile> A = new HashMap<Point,Tile>();
//Populating map
for(int i=0; i<2;i++){
for(int j=0; j<2;j++){
Tile t = new Tile(i, j, "OFF");
A.put(new Point(i,j), t);
}
}
//copying list1 to list2
Map<Point,Tile> B = new HashMap<Point,Tile>(A);
//Change tile on 1,1 to ON
Tile t2 = A.get(new Point(1,1));
t2.setS("ON");
for(int i=0; i<2;i++){
for(int j=0; j<2;j++){
Tile tTemp = A.get(new Point(i,j));
System.out.println(i+" "+j+" "+tTemp.getS());
}
}
//Reseting tiles
//clear first list
A.clear();
System.out.println("");
//copy second list to first list
A = new HashMap<Point,Tile>(B);
for(int i=0; i<2;i++){
for(int j=0; j<2;j++){
Tile tTemp = A.get(new Point(i,j));
System.out.println(i+" "+j+" "+tTemp.getS());
}
}
}
}
Here's the tile class
package main;
public class Tile {
public int x,y;
public String s;
public Tile(int x1, int y1, String st){
x=x1;
y=y1;
s=st;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
}
Here's what is getting printed before clearing HashMap A
0 0 OFF
0 1 OFF
1 0 OFF
1 1 ON
Here's what is getting printed After clearing HashMap A and then copy B to it.
0 0 OFF
0 1 OFF
1 0 OFF
1 1 ON
No difference.
However, when I changed tile (1,1) to ON on HashMap A , it updated HashMap B as well.
When you write:
Tile t2 = A.get(new Point(1,1));
t2.setS("ON");
you're not changing either of the maps. The maps just have references to Point
objects and Tile
objects. They have the same references - copying the map doesn't clone the objects within them.
So when you change the contents of one of those objects, you'll see that change regardless of which map you use to navigate to the object.
To put it another way, consider this situation:
Joe will see a red front door, yes? It's exactly the same here.
If you make your Point
and Tile
classes immutable, this won't be a problem - because you wouldn't be able to change the contents of existing objects. At that point there's no particularly meaningful difference between copying a reference and cloning the object. You'd end up writing something like:
Point p = new Point(1, 1);
Tile t2 = A.get(p);
t2 = t2.withS("ON"); // This would return a reference to a new object
A.put(t2);
See more on this question at Stackoverflow