HashMap保存数据的结构是数组+单向链表,它集成AbstractMap类以及实现Map接口:
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { //初始化大小16 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 //最大大小 static final int MAXIMUM_CAPACITY = 1 << 30; //默认加载因子 static final float DEFAULT_LOAD_FACTOR = 0.75f; static final Entry<?,?>[] EMPTY_TABLE = {}; transient Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE; /** * The number of key-value mappings contained in this map. */ transient int size;//map中key-value个数 /** * The next size value at which to resize (capacity * load factor). * @serial */ // If table == EMPTY_TABLE then this is the initial capacity at which the // table will be created when inflated. int threshold;//当size值大于等于threshold时需要扩容
HashMap有四个构造方法:
1、带初始化大小和加载因子的构造方法
public HashMap(int initialCapacity, float loadFactor)
public HashMap(Map<? extends K, ? extends V> m)
2、带初始化大小的构造方法
public HashMap(int initialCapacity)
3、无参构造方法
public HashMap()
4、带Map类型参数的构造方法
public HashMap(Map<? extends K, ? extends V> m)
在HashMap中,通过key的hash值来计算元素在数组table中的位置
int hash = hash(key); int i = indexFor(hash, table.length);
如果hash相等key也相等的话,则替换原来的值:
for (Entry<K,V> e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } }
如果不同的key计算出来的位置相同,则这些key-value组成单向链表,当实际的数据个数大于等于临界值threshold时,则需要以原大小的2倍的对table进行扩容:
void addEntry(int hash, K key, V value, int bucketIndex) { if ((size >= threshold) && (null != table[bucketIndex])) { resize(2 * table.length); hash = (null != key) ? hash(key) : 0; bucketIndex = indexFor(hash, table.length); } createEntry(hash, key, value, bucketIndex); } void resize(int newCapacity) { Entry[] oldTable = table; int oldCapacity = oldTable.length; if (oldCapacity == MAXIMUM_CAPACITY) { threshold = Integer.MAX_VALUE; return; } Entry[] newTable = new Entry[newCapacity]; transfer(newTable, initHashSeedAsNeeded(newCapacity));//重新计算位置并复制到新数组 table = newTable; threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1); }
并且需要重新计算数据再新数组中的位置并复制到新数组中。
通过key取value时,也是先通过key的hash计算位置,再遍历链表:
public V get(Object key) { if (key == null) return getForNullKey(); Entry<K,V> entry = getEntry(key); return null == entry ? null : entry.getValue(); } final Entry<K,V> getEntry(Object key) { if (size == 0) { return null; } int hash = (key == null) ? 0 : hash(key); //遍历链表 for (Entry<K,V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) return e; } return null; }
相关推荐
HashMap之resize()方法源码解读 HashMap的resize()方法是HashMap中最核心的方法之一,该方法负责扩容HashMap的容量,以便存储更多的键值对。下面我们将对HashMap的resize()方法进行源码解读,了解其扩容机制和原理...
hashmap源码解读,并且会对比JDK7和8实现的不同,已更新ConcurrentHashMap部分,且结合记录了多个视频的笔记。可以在https://blog.csdn.net/hancoder/article/details/105424922 获取最新笔记地址,下载过旧文件的...
HashMap 之 put 方法源码解读 HashMap 是 Java 中一种常用的数据结构,用于存储键值对。其中,put 方法是 HashMap 中最重要的方法之一,负责将键值对存储到HashMap 中。在本文中,我们将对 HashMap 的 put 方法的...
大厂HashMap面试源码解读,适合面试、初学者的人,HahsMap源码解读
HashMap 中红黑树 TreeNode 的 split 方法源码解读 HashMap 中红黑树 TreeNode 的 split 方法是 Java 中HashMap 的核心组件之一,负责将红黑树从旧数组转移到新数组上,并进行树链表的重新组织和优化。在本文中,...
这篇文章将对HashMap的一些核心知识点进行深入解读,特别关注于面试中常见的问题。 1. **HashMap的默认容量** HashMap的默认容量是16,这是通过构造函数中的`initialCapacity`参数指定的,如果未显式设置,则...
在Java的集合框架中,HashMap是一个非常重要的数据结构,它提供了高效的存储和查找元素的能力。在HashMap的实现中,为了优化性能,当链表长度达到一定阈值时,会将链表转换为红黑树(Red-Black Tree)。红黑树是一种...
Java源码解读是Java开发人员深入理解平台工作原理和编程模型的重要途径。在这个"java-src:java源码解读"项目中,我们可以探索Java的核心库,包括JVM(Java虚拟机)、集合框架、并发机制、I/O流、网络编程等多个关键...
在Java面试中,源码解读是一项重要的能力,它考察了开发者对Java语言底层实现的理解以及问题解决的能力。这里我们将深入探讨三道常见的Java面试题,它们涵盖了基础、并发和集合框架等方面,帮助你提升对Java源码的...
在Java编程语言的世界里,源码解读是提升技术深度、理解内部机制的关键步骤。"JavaSource:Java源码解读"项目旨在帮助开发者深入探索Java的内部工作原理,从而更好地运用和优化代码。在这个项目中,我们可以看到一...
Struts 1.2是该框架的一个版本,它的源码解读对于深入理解Struts的工作机制和原理至关重要。北大青鸟的这份文档是为了帮助学习者入门和精通Struts所编写的,包含了对Struts源码的详细解析。 首先,了解Struts的核心...
本篇文章将对Java API的部分关键组件进行源码解读,帮助读者深入理解其工作原理。 1. **对象创建与内存管理**: - `Object`类:所有Java类的基类,包含了如`clone()`, `equals()`, `hashCode()`等方法。理解`...
HashMap是Java编程语言中最常用的集合类之一,尤其在面试中,HashMap的相关知识是考察...这套学习资料应该包含了HashMap的实例分析、源码解读、常见面试题以及实战演练等内容,确保你全面掌握这一核心Java数据结构。
总的来说,理解HashMap中红黑树插入节点的调整过程需要深入理解红黑树的性质和旋转操作,同时熟悉HashMap源码中的编码风格和变量命名规则。通过这些知识,我们可以更好地掌握HashMap在处理大数据量时如何保持高效...
源码解读是提升技术水平的重要途径。例如,深入理解HashMap和ConcurrentHashMap的实现,可以让我们更好地利用这些数据结构,避免性能瓶颈;阅读ArrayList和LinkedList的源码,有助于我们选择合适的数据结构以优化...
Java作为一门广泛使用的编程语言,其底层知识点和源码解读对于深入理解并优化代码性能至关重要。本主题将探讨以下几个方面: 1. **Java虚拟机(JVM)**: JVM是Java程序运行的基础,它负责字节码的解释执行,内存...
《Java源码解读-ITG-JavaBook01: Java面试高频源码解读》是一部针对Java程序员面试准备的深入学习资料。在这个项目中,我们将会探索Java语言的一些核心概念和常用库的源代码,帮助开发者更好地理解Java的内部机制,...
HashMap、ConcurrentHashMap源码级解读,并且对比了JDK7和8实现的不同,进行了大量的解释,结合了多个学习视频
在本套课程中,将会非常深入、非常详细、非常全面的解读HashMap以及源码底层设计的思想。从底层的数据结构到底层源码分析以及怎样使用提高HashMap集合的效率问题等进行分析。如果掌握本套课程,那么再看其他javase的...