为简单起见,假设我有两个HashMap<String, String>
实例,它们共享相同的密钥。我想知道的是,它之间存在性能和内存差异,并在String
中表示这两个Object
值,并将它们存储在HashMap<String, Object>
中。
我的实际问题是使用HashMap<String, HashSet<String>>
的实例和HashMap<String, Double>
的两个实例,我希望通过合并它们,我会以某种方式节省内存,但我不确定是否有使用自定义Object
与HashSet
或Double
等本机对象作为值会对性能产生影响。
答案 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个字节。