2

为简单起见,假设我有两个实例HashMap<String, String>,它们共享相同的键。我想知道的是,这与将这两个String值表示为 anObject并将它们存储在HashMap<String, Object>.

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

4

4 回答 4

5

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

速度

对于速度影响,请记住在 aHashMap<String, ?>中,String是被散列的内容。实际上,您可能会看到速度略有提高,因为与 3 次查找相比,您只需进行一次查找即可找到您的自定义对象。

空间

对于空间影响,请记住HashMap使用大小为 2 次方的内部数组。如果您只HashMap使用没有特殊设置(如自定义负载因子)的 vanilla,那么您可能会看到空间略有增加,因为现在您有(粗略,当然,这只是简化了):

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

组合起来之后,你将拥有

CustomObject[]
    HashSet<String>
    Double
    Double

这是忽略不随地图增长的恒定大小信息。对象占用的空间不仅仅是对其字段的引用,但不是很多。

易读性

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

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

于 2012-10-17T17:56:12.133 回答
1

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

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

HashMap<String, MyStuff> map;

这肯定会节省内存,因为您将拥有更少的地图条目。

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

于 2012-10-17T17:58:12.133 回答
0

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

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

于 2012-10-17T17:58:57.857 回答
0

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

于 2012-10-17T18:00:34.447 回答