哈希映射值如何存储(如果值重复)?

时间:2019-01-21 12:35:57

标签: java collections hashmap

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的值完全相同)

我关心的是调整大小,因为我要保存的值很大,没有意义重复它们。

4 个答案:

答案 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()方法)。