关于HashMap put()和get()方法如何工作的内部结构(仅基本逻辑)

当我们使用put()方法在HashMap类中放置一个键实例说“key”和一个Value实例说“value”时, HashMap类在内部做了什么。 当我们说hashMap.get(key)时,它如何检索值?

编辑 :我不想要这里的细节,基本上试图理解更大的图片以及equals()hashcode()方法在put()get()操作中的作用。

如果你谈论更高的画面,它就像下面一样。这里我把项目称为Mapkey

放置物品时。

  1. 计算密钥的hashcode
  2. 如果存在具有该hashcode basket ,则使用键上的equals方法搜索该篮子中的键以确定是否要添加或替换该元素。
  3. 如果不存在则创建新的篮子(重新散列)并将该元素添加到该篮子中。

得到:

  1. 获取密钥的hashcode
  2. 去那个篮子
  3. 在键上使用equals迭代将从该篮子中返回该元素。

这是在IBM jdk 1.6中完成的(我相信它对所有供应商来说都是一样的)

编辑

关于equalshashcode您可能有兴趣看到这篇文章。

编辑结束

  /** * Maps the specified key to the specified value. * * @param key * the key * @param value * the value * @return the value of any previous mapping with the specified key or null * if there was no mapping */ @Override public V put(K key, V value) { return putImpl(key, value); } V putImpl(K key, V value) { Entry entry; if(key == null) { entry = findNullKeyEntry(); if (entry == null) { modCount++; if (++elementCount > threshold) { rehash(); } entry = createHashedEntry(null, 0, 0); } } else { int hash = key.hashCode(); int index = hash & (elementData.length - 1); entry = findNonNullKeyEntry(key, index, hash); if (entry == null) { modCount++; if (++elementCount > threshold) { rehash(); index = hash & (elementData.length - 1); } entry = createHashedEntry(key, index, hash); } if ((cache != null) && (hash >> CACHE_BIT_SIZE == 0) && (key instanceof Integer)) { cache[hash] = value; } } V result = entry.value; entry.value = value; return result; } 

java 8开始,对于HashMap对象有一个性能改进,其中通过使用平衡树而不是链接列表来存储映射条目,密钥中存在大量冲突。 主要思想是,一旦哈希桶中的项目数量增长超过某个阈值,该桶就会从使用链接的条目列表切换到平衡树。 在高哈希冲突的情况下,这将改善从O(n)O(log n).最坏情况性能O(log n).

基本上当存储桶变得太大时(目前: TREEIFY_THRESHOLD = 8 ), HashMap动态地将其替换为树形图的临时实现。 这种方式而不是悲观的O(n)我们得到更好的O(log n)

TreeNodes Bins(元素或节点)可以像其他任何一样遍历和使用,但是当人口过多时还支持更快的查找。 但是,由于正常使用的绝大多数垃圾箱都不是人口过多,因此在表格方法的过程中可能会延迟检查树箱的存在。

Tree容器(即其元素都是TreeNodes )主要由hashCode排序,但在tie的情况下,如果两个元素具有相同的“ class C implements Comparable ”,则键入其compareTo()方法为用于订购。

由于TreeNodes的大小约为常规节点的两倍,因此我们仅在bin包含足够节点时才使用它们。 当它们变得太小(由于移除或resize)时,它们被转换回普通箱(目前: UNTREEIFY_THRESHOLD = 6 )。 在具有良好分布的用户hashCodes用法中,很少使用树容器。

链接到java doc

集合框架增强function