如何在Java中复制HashMap(不是浅层复制)

2022-08-31 15:22:46

我需要制作副本,但是当我更改副本中的某些内容时,我希望原始内容保持不变。即,当我从副本中删除某些内容时,它会保留在原始副本中。HashMap<Integer, List<MySpecialClass> >List<MySpecialClass>List<MySpecialClass>

如果我理解正确,这两种方法只会创建浅层副本,这不是我想要的:

mapCopy = new HashMap<>(originalMap);
mapCopy = (HashMap) originalMap.clone();

我说的对吗?

有没有比循环访问所有键和所有列表项并手动复制它更好的方法?


答案 1

不幸的是,这确实需要迭代。但是对于Java 8流来说,这是非常微不足道的:

mapCopy = map.entrySet().stream()
    .collect(Collectors.toMap(e -> e.getKey(), e -> List.copyOf(e.getValue())))

答案 2

你是对的,浅层副本不符合你的要求。它将具有来自原始映射的s的副本,但这些副本将引用相同的对象,因此对一个的修改将出现在来自另一个的相应中。ListListListListHashMapListHashMap

在 Java 中没有为 提供深度复制,因此您仍然必须遍历新 .但是您还应该每次都制作一份副本。像这样:HashMapputHashMapList

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;
}

如果要修改单个对象,并且更改不会反映在复制的 s 中,则还需要制作它们的新副本。MySpecialClassListHashMap