没有明确的答案:哪个Java地图最便宜?

没有明确的答案:哪个Java地图最便宜?,java,performance,map,key,Java,Performance,Map,Key,以前可能有人问过这个问题,但我一次又一次地遇到这种情况,我想储存一小部分财产,我绝对肯定这些财产永远不会超过20把钥匙。使用HashMap似乎完全浪费了CPU和内存,一开始就有这么多开销,但在计算每个键查找的高级哈希值时性能也很差。如果你的第一段只有,没有不会有太大的内存开销,因为据我所知,HashMap是用16个bucket初始化的,然后每次重新灰化时它的大小都会翻倍,所以在最坏的情况下,你的map会有12个多余的bucket,所以这没什么大不了的 关于查找时间,它是常数,相当于访问数组元素的

以前可能有人问过这个问题,但我一次又一次地遇到这种情况,我想储存一小部分财产,我绝对肯定这些财产永远不会超过20把钥匙。使用HashMap似乎完全浪费了CPU和内存,一开始就有这么多开销,但在计算每个键查找的高级哈希值时性能也很差。如果你的第一段只有,没有不会有太大的内存开销,因为据我所知,
HashMap
是用16个bucket初始化的,然后每次重新灰化时它的大小都会翻倍,所以在最坏的情况下,你的map会有12个多余的bucket,所以这没什么大不了的

关于查找时间,它是常数,相当于访问数组元素的时间,这总是比在
O(n)
元素上循环要好(即使n<20)。<>代码> HashMap <代码>的唯一背景是它不被排序,但就我而言,我认为它是默认的<代码> map < /Cord>在java中没有特殊要求。
总结一下:使用HashMap

> p> >如果您担心代码“> HASCODE())/<代码在您的密钥上的计算时间,考虑缓存计算值,例如,<代码> java .Lang.Stist< /Cuth>。请参阅关于这一点的问题。

警告:我建议您认真对待过早优化。对于大多数应用程序中的大多数程序员,我严重怀疑您是否需要担心
映射的性能。更重要的是考虑并发、迭代顺序和空值的需要。但既然你问了,下面是我的具体答案

EnumMap
如果您的键是,那么您最快的
Map
实现将是

基于表示枚举对象域的位图,
EnumMap
在使用很少内存的情况下执行速度非常快

IdentityHashMap
<>如果你真的很关心性能,那就考虑使用.
Map
的这个实现使用引用相等而不是对象相等。虽然仍然有一个散列值,但它是内存中对象地址的散列(也就是说,Java中没有直接的内存访问)。因此,完全避免了对每个键对象自己的方法可能很长的调用。因此,性能可能比性能更好。您将看到基本操作的恒定时间性能(
get
put

仔细研究文档,看看是否要走这条路。请注意关于线性探测与链接的讨论,以获得更好的性能。请注意,此类在一定程度上破坏了在比较对象时强制使用
equals
方法的约定。而且这个映射不提供并发性


下面是我制作的一个表,用于比较与Java11捆绑的各种
Map
实现


只使用数组如何?@hatchet它不会比
HashMap
更有效(也就是说,HashMap包含一个数组),并且无法读取,尤其是当数组不是完全可用时filled@Dici-5个元素?这就像是把你的车开下30英尺的车道去拿你的邮件。如果OP同时担心空间和时间成本,那么阵列将赢得空间,在时间上无法区分,但也可能更快。@hatchet他可以利用初始容量和负载系数。如果他手动使用数组,那么这么小的开销与他必须编写的丑陋代码相比根本算不了什么。这可能是毫无意义的,因为说实话,我很难相信这在你的应用程序中真的很重要。如果这不重要,可读性/可维护性将获胜。在这一点上,我同意@Dici。我同意查找时间是恒定的,但计算散列如何等同于遍历数组?这取决于您的散列函数,但通常不会太昂贵。我的观点是,您不应该阻止使用高级数据结构进行优化。代码可读性和功能性是您的首要任务。另外,当遍历数组时,必须调用
equals
(多次),其运行时间可以与
hashCode
(只调用一次)相当。好的回答!因此,我可以安全地继续我的实践,始终使用HashMaps然后。很高兴知道。如果你不在乎订购,是的。要优化使用
HashMap
,请了解负载系数和初始容量如何影响重新灰烬的数量(这是使用
HashMap
时真正需要的时间)。然而,老实说,我几乎从不关心这一点,而是使用默认构造函数。知道何时需要优化代码以达到性能目标是很好的。不要试图质疑结论,但当n仅为20时,不能使用O表示法来争论速度。当你比较O(1)和O(N)时,你是在比较O(1xa)和O(20xb),而不知道每边的常数因子a和b到底有多大。