这是一个老问题,但我认为还有其他要提到的事情。
如果你只想创建一个浅拷贝的映射,那么选项3是最推荐的。
然而,如果你需要复制一个被定义为 HashMap<Integer, List<Item>>
的映射,但你希望在复制品中更改某些内容时原始映射保持不变。也就是说,如果你从复制品的列表中删除了某些内容,则原始列表应该保持原值。
我有两个解决方案,一个是深度复制函数。目前Java 8没有提供本地实现。我们可以使用Guava或Apache Commons Lang。但我们可以通过创建一个方法来创建新实例,使用foreach
方法或Stream.collect()
方法来找到一个解决方法。前者很简单,我们使用foreach来创建我们想要复制的对象的新实例,在这种情况下是List<T>
。请查看此处的通用函数:
public static <T> HashMap<Integer, List<T>> deepCopy(HashMap<Integer, List<T>> original)
{
HashMap<Integer, List<T>> copy = new HashMap<>();
for (Map.Entry<Integer, List<T>> entry : original.entrySet()) {
copy.put(entry.getKey(), new ArrayList<>(entry.getValue()));
}
return copy;
}
如果您不想处理泛型,那么我们将使用Stream.collect()
。在这种情况下,我们使用流来提取数据并将其包装为映射,并创建一个新实例。
public static <T> Map<Integer, List<T>> deepCopyStream(Map<Integer, List<T>> original)
{
return original
.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, valueMapper -> new ArrayList<>(valueMapper.getValue())));
}
注意
请注意,我没有在泛型中使用<K,V>
,因为这不是一个适用于每个层级的嵌套克隆的正确深度复制方法。这种方法基于我们有一个HashMap<Integer, List<Item>>
,其中Item
类不包含需要克隆的属性。