如何从java HashMap获取不可变集合?

我需要从java HashMap中获取一个集合,而不会在以后的集合中反映地图中的更改。 我想使用Collection.toArray()来实现这一点,但它不起作用。 结果Object []也在改变(javadocs说返回的数组将是“安全的”,因为此集合不会保留对它的引用)。 有任何简单的方法来实现这一目

使用单个API调用无法实现此function,您需要利用深度克隆。 更改原始文件时,不会更改克隆。 此主题之前已在SO上讨论过,请参阅如何克隆ArrayList并克隆其内容? 和深度克隆实用程序推荐 。

Google系列Immutable Map可能对您有所帮助。

另见Collections.unmodifiableMap

您可以创建不可修改的地图

以下内容仍然有效,并描述了观察到的问题(请参阅执行何种副本的位)。 但是,我没有就如何执行深层复制提供任何答案。

相反, 我的建议是将对象设计为不可变的 ,这完全避免了这个问题。 根据我的经验,这对于大多数琐碎的对象(即不是“容器”的对象)非常有效,并且可以简化代码和推理。


从Javadoc for HashMap.values

返回此映射中包含的值的Collection视图。 该集合由地图支持 ,因此对地图的 更改将反映在集合中 ,反之亦然……

也许创建它的副本会有好处吗?

 HashMap map = ....; List values = new ArrayList(map.values()); 

实质上,这是执行“现在分开”的浅拷贝 。 但是, 作为浅拷贝 ,不执行所包含对象的克隆/拷贝 。 (如果需要深拷贝语义,请参阅答案:问题本身在这个问题上看起来有点模糊。)

快乐的编码

使用HashMap.clone HashMap.clone()创建原始映射的浅表副本,然后从中检索值收集。 这将在clone()调用时创建对原始映射中对象的新引用; 显然,包含的对象内部的更改仍将反映在复制的集合中。 如果您想要这种行为,您唯一的方法是在所需的集合中硬拷贝地图对象。