我在将 HashMap A 复制到 HashMap B 时遇到问题。B 始终与 A 相同。我的想法是仅使用 HashMap 制作一个小型瓷砖游戏。
Map<Point,Tile> A = new HashMap<Point,Tile>();
HashMap 有两件事。一个点(键)和一个图 block 对象,这是我制作的另一个类。 Tile 接受两个整数和一个字符串。 (新瓷砖(x,y,字符串))。前两个整数定义点 x 和 y,字符串表示其是“OFF”还是“ON”。
我首先要做的是用 2*2 元素填充 HashMap A。
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);
}
}
然后我通过在构造函数中添加 A 将 HashMap A 复制到 HashMap B。我的想法是这样我可以通过在构造函数中使用 HashMap B 回到默认的 HashMap A(见下文)
Map<Point,Tile> B = new HashMap<Point,Tile>(A);
然后我将图 block (1,1) 更改为“ON”
Tile t2 = A.get(new Point(1,1));
t2.setS("ON");
我的一个图 block 现在处于“开启”状态。现在我想将板重置回原来的状态(在填充阶段之后)。我清除 HashMap A 并以 HashMap B 作为构造函数创建一个新的 HashMap。
A.clear();
A = new HashMap<Point,Tile>(B);
但是,当我将 HashMap A 上的tile (1,1)更改为ON时,它也更新了HashMap B。我认为用构造函数创建一个新的 HashMap 会创建它的新副本,但似乎不起作用。
奇怪的是
Map<Point,String> A = new HashMap<Point,String>();
可以,但不行
Map<Point,Tile> A = new HashMap<Point,Tile>();
我想以某种方式获取 HashMap A 的原始内容,而不需要再次尝试循环元素。
这是我的主类代码
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());
}
}
}
}
这是图 block 类
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;
}
}
这是清除 HashMap A 之前打印的内容
0 0 OFF
0 1 OFF
1 0 OFF
1 1 ON
这是清除 HashMap A 并将 B 复制到其中后打印的内容。
0 0 OFF
0 1 OFF
1 0 OFF
1 1 ON
没有区别。
最佳答案
您需要通过Tile
对象克隆来深层复制您的HashMap
。
默认情况下,HashMap
构造函数正在执行浅复制。它只是从传入的 Map
中复制值,这适用于基元、String
(以及其他不可变) em> 对象),但不适用于对 Object
类型的引用,因为复制的引用将指向相同的原始对象,因此稍后会对其进行修改。
因此,要解决此问题,只需实现一个深层复制方法即可
public Map<Point, Tile> getDeepCopy(Map<Point, Tile> source) {
Map<Point, Tile> copy = new HashMap<Point, Tile>();
for (Map.Entry<Point, Tile> entry : source.entrySet())
copy.put(entry.getKey(), entry.getValue().clone());
return copy;
}
并使您的 Tile
类实现 Cloneable
并覆盖 clone()
方法为
public class Tile implements Cloneable {
// other implementation
public Tile clone() throws CloneNotSupportedException {
return (Tile) super.clone();
}
}
您使用 Point
的方式,我认为也没有必要 clone()
它们,但如果您希望它们深入-同样克隆,只需修改为上面的Tile
即可。
关于java - 将 HashMap 复制到另一个 HashMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29139497/