我需要制作HashMap<Integer, List<MySpecialClass> >
的副本,但当我更改副本中的某些内容时,我希望原始版本保持不变。也就是说,当我从副本中删除List<MySpecialClass>
中的内容时,它会保留在原始的List<MySpecialClass>
中。
如果我理解正确的话,这两种方法只会创建我不想要的浅拷贝:
mapCopy = new HashMap<>(originalMap);
mapCopy = (HashMap) originalMap.clone();
我说的对吗?
有没有更好的方法来做到这一点,而不是只迭代所有的键和所有的列表项,并手动复制它?
发布于 2015-02-03 07:16:14
你说得对,肤浅的拷贝不能满足你的要求。它将具有原始地图中的List
的副本,但这些List
将引用相同的List
对象,因此一个List
中对HashMap
的修改将出现在另一个List
中的相应HashMap
中。
在Java语言中,没有为HashMap
提供深度复制,因此您仍然需要遍历所有条目,并在新的HashMap
中对它们执行put
操作。但您也应该每次都复制一份List
。如下所示:
public static HashMap<Integer, List<MySpecialClass>> copy(
HashMap<Integer, List<MySpecialClass>> original)
{
HashMap<Integer, List<MySpecialClass>> copy = new HashMap<Integer, List<MySpecialClass>>();
for (Map.Entry<Integer, List<MySpecialClass>> entry : original.entrySet())
{
copy.put(entry.getKey(),
// Or whatever List implementation you'd like here.
new ArrayList<MySpecialClass>(entry.getValue()));
}
return copy;
}
如果要修改单个MySpecialClass
对象,并且不希望更改反映在复制的HashMap
的List
中,则还需要创建新的副本。
发布于 2015-02-03 07:25:02
不幸的是,这确实需要迭代。但对于Java 8 streams来说,这是相当微不足道的:
mapCopy = map.entrySet().stream()
.collect(Collectors.toMap(e -> e.getKey(), e -> List.copyOf(e.getValue())))
发布于 2017-09-06 20:02:26
序列化到json,然后反序列化:
Map<String, Object> originalMap = new HashMap<>();
String json = new Gson().toJson(originalMap);
Map<String, Object> mapCopy = new Gson().fromJson(
json, new TypeToken<Map<String, Object>>() {}.getType());
对于特殊的类,您可能需要write a custom deserializer。
https://stackoverflow.com/questions/28288546
复制相似问题