【发布时间】:2015-06-13 13:01:21
【问题描述】:
我有一个 Hashmap,我在其中编写了一个处理添加和检索值的类。
class ReputationMatrix
{
private HashMap < Integer, int[] > repMatrix;
public ReputationMatrix()
{
repMatrix = new HashMap < Integer, int[] > ();
}
public void addrating(int nodeId, boolean rating)
{
int[] alphaBeta;
if (repMatrix.containsKey(nodeId))
{
alphaBeta = repMatrix.get(nodeId);
if (rating == true)
{
alphaBeta[0] = alphaBeta[0] + 1;
}
else
{
alphaBeta[1] = alphaBeta[1] + 1;
}
repMatrix.put(nodeId, alphaBeta);
}
else
{
alphaBeta = new int[2];
if (rating == true)
{
alphaBeta[0] = 2;
alphaBeta[1] = 1;
}
else
{
alphaBeta[0] = 1;
alphaBeta[1] = 2;
}
repMatrix.put(nodeId, alphaBeta);
}
}
public int[] getNodeIds()
{
int[] nodeIds = new int[repMatrix.size()];
int index = 0;
for (int key: repMatrix.keySet())
{
nodeIds[index] = key;
index++;
}
return nodeIds;
}
public int getAlpha(int nodeId)
{
return repMatrix.get(nodeId)[0];
}
public int getBeta(int nodeId)
{
return repMatrix.get(nodeId)[1];
}
public ReputationMatrix clone()
{
ReputationMatrix matrixClone = new ReputationMatrix();
matrixClone.repMatrix.putAll(this.repMatrix);
return matrixClone;
}
}
我实现了一个克隆方法来简单地返回一个完全独立于原始的 ReputationMatrix 的单独副本。
我测试了这样的代码:
public class Main
{
/**
* @param args
*/
public static void main(String[] args)
{
ReputationMatrix matrix1 = new ReputationMatrix();
matrix1.addrating(18, true);
ReputationMatrix matrix2 = matrix1.clone();
System.out.println(matrix1.getAlpha(18));
System.out.println(matrix2.getAlpha(18));
matrix1.addrating(18, true);
System.out.println(matrix1.getAlpha(18));
System.out.println(matrix2.getAlpha(18));
}
}
输出是:
2
2
3
3
这意味着我对 matrix1 应用的每一个更改都会反映在 matrix2 上。 我几乎可以肯定 putAll 确实会创建副本。我做错了什么?
【问题讨论】:
-
.putAll()从不做“深拷贝”;它只做浅拷贝。你从哪里读到它做了深拷贝? -
put 和 putall 只是存储对对象的引用。
-
也许我错了。所以我可以克隆 Hashmap 的唯一方法是遍历所有键并克隆数组?
-
在 Java 中你永远不会自动获得副本,它必须是显式的。有一个根本原因:复制对象图是一个定义不明确的概念,一般情况下无法解决。