Java HashMap
是将重复值保存为唯一值还是将其单独保存?
假设我有以下键值对值:
A -> "a very long string...."
B -> "another very long string...."
C -> "the same very long string from A key.... (but not same string instance)"
将其保存为3个键和3个值,或另存为3个键和2个值(因为A
的值与C
的值完全相同)
我关心的是调整大小,因为我要保存的值很大,没有意义重复它们。
答案 0 :(得分:3)
HashMap
可以包含重复的值,因此在您的示例中,Map
中将有3个键和3个值。
但是,如果您担心大型实例将多次存储为Map
中的值,则应存储对同一实例的引用。
例如:
String val = "a very long String............";
String val2 = "a second long String.........";
map.put(1,val);
map.put(2,val2);
map.put(3,val);
只有两个大型String
实例。 Map
包含3个对这些String
的引用(两个对第一个String
的引用和一个对第二个String
的引用),但是引用占用的存储量很小。
答案 1 :(得分:2)
它不保留值,而是保存对值的引用,因此问题归结为以下问题:“ "a very long string...."
和"the same very long string from A key...."
是否在内存中是同一对象?”
如果它们不是编译时常量,并且在运行时获取/构造,则它们是不同的对象。字符串实习以及String#intern
可以在这里为您提供帮助,但是@bratkartoffel提到了它的局限性。
What is Java String interning?
When should we use intern method of String on String literals
Performance penalty of String.intern()
答案 2 :(得分:2)
但是这个无关 HashMap
,我的意思是它不是专门针对它的。将值设为String
也意味着另外两个不同的事物-例如String插入或String
是不可变的事实。同样,HashMap
不会复制值(可能意味着什么),它仅存储对其他对象的引用-您完全可以使用这些对象来完成操作。如果您在HashMap
之外更改对象,然后针对该特定的关联键查询Map
,则将看到更新。
答案 3 :(得分:1)
Java HashMap
不允许重复的键,但允许重复的值。因此会将它们保存为3个键和3个值。
为使它不会两次保存值,您将必须检查它(例如,使用.containsValue()
方法)。