java - 将 HashMap 复制到另一个 HashMap

标签 java dictionary hashmap copy

我在将 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/

相关文章:

java - 永不更改表的最佳 Spring/Hibernate 配置

java - 使用 Picasso 将图像加载到位图中

python - 如何使用 map 和 reduce 在 Python 中按步骤组成函数列表

python - 迭代 pandas DataFrame 中的行并创建一个字典

java - 从 EJB 或 Java EE webapp 使用 http 资源的最佳方式

java - JpaRepository.findOne() 对 JpaRepository.getOne() 的影响

python - 为什么当我点击 Dictionary 变量时 Spyder 不能打开它?

python - 生成随机数作为python中字典的值

java - 将表 Guava 用于 hashbasedTable

java - Java中的keyComparator是什么?