HashMap的两个实例之间的区别<string,string =“”>和HashMap的实例<string,object>其中Object包含两个字符串</string,object> </string,>

时间:2012-10-17 17:53:01

标签: java hashmap

为简单起见,假设我有两个HashMap<String, String>实例,它们共享相同的密钥。我想知道的是,它之间存在性能和内存差异,并在String中表示这两个Object值,并将它们存储在HashMap<String, Object>中。

我的实际问题是使用HashMap<String, HashSet<String>>的实例和HashMap<String, Double>的两个实例,我希望通过合并它们,我会以某种方式节省内存,但我不确定是否有使用自定义ObjectHashSetDouble等本机对象作为值会对性能产生影响。

4 个答案:

答案 0 :(得分:5)

哈希值是根据字符串计算的,因此不会产生速度影响。从长远来看,空间影响(非常轻微的增加)可以忽略不计。如果它使代码更清晰,那就去做并搞砸性能(只要我们没有谈论巨大的性能瓶颈,那就无所谓了。)

<强>速度

对于速度影响,请记住在HashMap<String, ?>中,String会被哈希处理。实际上,您可能会看到速度略有增加,因为与3次查找相比,您只需要执行一次查找来查找自定义对象。

空格

对于空间影响,请记住HashMap使用的内部数组的大小为2的幂。如果您只使用香草HashMap而没有像自定义加载因子这样的特殊设置,然后你可能会看到一个微小的空间增加,因为你现在(大致,当然,这只是简化):

HashSet<String>[]
Double[]
Double[]

在合并之后,你将拥有

CustomObject[]
    HashSet<String>
    Double
    Double

这忽略了不随地图增长的常量信息。对象占用的空间不仅仅是对其字段的引用,而且不是很多。

<强>易读性

自定义对象选项赢得了这一项。它更干净,非常OOP,非常适合Java。无论性能如何,无论如何都应该这样做。从长远来看,它看起来会更好,并且更易于维护。

例如,如果要向自定义对象添加字段,那很容易。但是拥有单独的地图意味着为更多变量创建更多地图,这是很脏的。我说去OOP方式。

答案 1 :(得分:1)

如果要组合它们,请创建一个表示它们的类,并有一个映射:

public class Stuff {
    String a;
    String b;
    // other fields - maybe the double you mentioned
}

HashMap<String, MyStuff> map;

这肯定会节省内存,因为你的地图条目会更少。

然而,无论如何,这是正确的方法。设计时间不是担心微小性能和内存影响的时候。使您的代码易于阅读和使用,您的生活(和代码)将更好。

答案 2 :(得分:0)

除非您正在处理大量条目,否则差异(如果有的话)可能并不重要。它也将与平台(JVM版本,Java库版本等)密切相关,因此您唯一有用的答案将来自于针对每种不同方式运行的分析器。

您可以考虑查看Guava Multimap。它可能是一个更清洁的解决方案。如果做不到这一点,我会使用自定义对象。代码清晰度每次都会过早优化。

答案 3 :(得分:0)

通过组合表格,你在很多方面可能会更好。在Speedwise中,您只需计算哈希值并遍历哈希链一次而不是两次。对于空间,您只需要一个哈希表而不是两个哈希表(如果加载因子大约为50%,则每个条目保存大约8个字节)和一个哈希链而不是两个哈希链(每个条目保存一个哈希链对象大约16个字节)。您支付配对对象的费用,但最多只需16个字节。