Java映射实现渐进复杂性(HashMap、LinkedHashMap、TreeMap)

Java映射实现渐进复杂性(HashMap、LinkedHashMap、TreeMap),java,algorithm,collections,hashmap,time-complexity,Java,Algorithm,Collections,Hashmap,Time Complexity,我试图处理HashMap、LinkedHashMap和TreeMap的渐进复杂性。在不同的网站和文章上写下,平均来说,get=O(1),最坏的情况是-O(n)。(如果所有钥匙添加到一个铲斗) 但我读了《java思考》一书,书中有一个比较的例子 如果您查看此数据,则会显示出O(n) 我完全糊涂了。谁能解释一下Map实现-HashMap、LinkedHashMap和TreeMap的不对称复杂性,至少对于get和put?(也许有一篇好文章,其中所有内容都很清楚并放在一起?) 编辑 对put方法最感兴

我试图处理
HashMap
LinkedHashMap
TreeMap
的渐进复杂性。在不同的网站和文章上写下,平均来说,
get
=
O(1)
,最坏的情况是-
O(n)
。(如果所有钥匙添加到一个铲斗)

但我读了《java思考》一书,书中有一个比较的例子

如果您查看此数据,则会显示出
O(n)

我完全糊涂了。谁能解释一下
Map
实现-
HashMap
LinkedHashMap
TreeMap
的不对称复杂性,至少对于
get
put
?(也许有一篇好文章,其中所有内容都很清楚并放在一起?)

编辑

put
方法最感兴趣。因为当某个特定的大小出现时,
resize()
类似于
ArrayList
它被称为摊销
O(1)
,这意味着在一段时间内,当有许多条目时,您通常会得到
get
。你似乎也缺乏对O(1)的理解——这意味着,它是恒定的。如果我向
HashMap
添加更多条目,则检索条目所需的时间是相同的,无论是该
HashMap
中的1000万条条目还是1000万条条目,并且考虑到
hashCode
已经实现,并且没有
return 1
的虚拟实现(例如,此时条目将被放入同一个存储桶中)

在某些情况下确实会发生调整大小的操作,但这与
ArrayList
的操作方式并不接近。
ArrayList
总是会使内部数组变大;
HashMap
会将内部存储桶增加一倍,直到某一点(),之后它会将某个bucket转换为一个
,使搜索速度更快-这是在java-8中添加的。

它被称为摊销
O(1)
,意思是在一段时间内,当有许多条目时,您通常会
获取
。您似乎也缺乏对
O(1)的理解
-这意味着它是常量。如果我向
HashMap
添加更多条目,则检索条目所需的时间是相同的,可以是该
HashMap
中的1000万或1000万条条目,并考虑到
hashCode
已实现且没有
return 1
的虚拟实现(例如,此时条目将被放入同一个存储桶中)


在某些情况下确实会发生调整大小的操作,但这与
ArrayList
的操作方式并不接近。
ArrayList
总是会使内部数组变大;
HashMap
会将内部存储桶增加一倍,直到某一点(),之后它会将某个bucket转换为
,使搜索速度更快-这是在java-8中添加的。

老实说,我不知道这些没有任何单位的数字应该告诉我什么。它们甚至看起来不一致。此外,
HashMap
TreeMap
具有根本不同的时间复杂性是的,所以一次性要求它们是没有意义的。老实说,我不知道这些没有任何单位的数字应该告诉我什么。它们甚至看起来不一致。而且,
HashMap
,和
TreeMap
具有根本不同的时间复杂性,所以一次性要求它们是没有意义的。
HashMap
的“调整大小”操作将使存储桶的数量加倍,这反过来将减少在特定存储桶中需要树的可能性,而不是提高它。将存储桶列表转换为树可能更倾向于在
put
操作中独立地进行调整大小操作。@Holger
resize
将加倍,直到两个的阈值都达到e> TREEIFY_THRESHOLD
MIN_TREEIFY_CAPACITY
达到之后,特定的bucket被转换为树并保持这种方式(除非条目被删除到某一点);这是我的观点vs
ArrayList
的调整大小,它总是会增加大小。我对你的第二点也有点困惑(“独立”让我困惑),当容量翻倍时,由于将从
put
内调用
resize
,每个旧存储桶中的项目将根据其实际哈希代码转移到两个新存储桶中。因此,每个新存储桶中的项目数最多与旧存储桶中的项目数相同,但可能较少。因此,提高容量可能会导致e结果桶中的项目数降到
未审阈值
以下,但不升到
TREEIFY\u阈值以上(之前未超过该阈值)。您似乎过于关注小映射的情况,但在讨论渐近时间复杂性时,小映射是不相关的。@Holger啊!现在我明白了您的意思是,感谢您的评论
HashMap
的调整大小操作将使桶的数量增加一倍,这反过来将减少在特定桶中需要树的可能性,而不是提高它。将桶的列表转换为树可能更倾向于在
put
操作中独立地进行调整大小操作。@Holger
 resize
将加倍,直到达到
TREEIFY_threshold
MIN_TREEIFY_CAPACITY
的阈值,然后,将特定存储桶转换为树并保持这种方式(除非将条目删除到某一点);这是我对调整
ArrayList
大小的观点,它总是会增加大小。我对你的第二点也有点困惑(“独立”让我困惑),当容量翻倍时,由于将从
put
内调用
resize
,每个旧桶的项目将转移到两个新桶,具体取决于