HashMap是Java集合框架中最常用的一个Map实现,其基本原理是通过将键值对映射到一个数组中,使用链表或红黑树解决哈希冲突。put()方法是HashMap中最常用的方法之一,它用于添加一个键值对到HashMap中。
一、Java HashMap的工作原理
HashMap在存储键值对时,首先经过哈希函数的映射,将键值对映射到一个数组中。这个数组被称为哈希表。但是由于不同的键值对可能会映射到同一个位置上,因此出现了哈希冲突。解决哈希冲突的方式主要有两种,一种是使用链表法,另一种是使用红黑树。
在JDK1.8之前,HashMap使用链表法解决哈希冲突。在JDK1.8之后,当链表长度超过8时,链表将转换成红黑树,以提高其性能和效率。
二、Java HashMap的put()方法实现
put()方法是HashMap中最常用的方法之一,它用于添加一个键值对到HashMap中。下面是put()方法的实现:
public V put(K key, V value) { if (table == EMPTY_TABLE) { inflateTable(threshold); } if (key == null) return putForNullKey(value); int hash = hash(key); int i = indexFor(hash, table.length); for (Entrye = 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; } } modCount++; addEntry(hash, key, value, i); return null; }
该方法首先判断当前的哈希表是否为空,如果为空,则先对哈希表进行扩容。接着判断键是否为null,如果是null,则调用putForNullKey()方法添加键值对。如果不是null,则对键值对进行哈希计算,并找到键值对应的位置。接着遍历该位置上的链表,如果发现当前键已经存在于链表中,则更新其对应的值。如果不存在,则将该键值对添加到链表末尾。
三、Java HashMap的扩容机制
当HashMap中的键值对数量超过threshold时,就需要对HashMap进行扩容。扩容操作会重新计算哈希值,并将每个键值对重新映射到新的数组中。下面是expand()方法的实现:
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); table = newTable; threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1); }
该方法首先判断是否已经达到了HashMap的最大容量,如果达到了,则退出扩容。否则,创建一个新的链表数组,并将每个键值对重新映射到新的数组中。在重新映射过程中,需要调用hash()方法重新计算哈希值,并调整每个键值对在新数组中的位置。
四、Java HashMap的线程安全性
HashMap在多线程环境下不是线程安全的。如果需要在多线程环境下使用HashMap,可以使用ConcurrentHashMap或通过synchronized关键字进行加锁。
五、Java HashMap中的性能优化
一般来说,为了提高HashMap的性能,需要尽量减少哈希冲突的发生。在添加键值对时,可以尝试让哈希函数返回较为分散的哈希值,以减少键值对映射到同一位置上的可能性。
同时,当链表长度过长时,可以将链表转化为红黑树,以提高查找效率。另外,还可以通过调整加载因子的大小来控制HashMap的性能。
六、Java HashMap的应用场景
HashMap常用于存储键值对,并且具有快速添加、查找和删除的特点。HashMap在Java集合框架中被广泛地应用于缓存、网络传输、日志处理等领域。
七、Java HashMap的完整代码
import java.util.HashMap; import java.util.Map; public class Main { public static void main(String[] args) { Map<String, Integer> map = new HashMap<>(); map.put("John", 25); map.put("Alice", 30); if (map.containsKey("John")) { System.out.println("John is " + map.get("John") + " years old."); } } }
该程序使用HashMap存储两个人的年龄信息,并在控制台输出John的年龄。