HashMap
HashMap底层是一个Entry[]数组;当发生hash冲突的时候,hashMap是采用链表的方式来解决;在对应的数组位置存放链表的头节点;新加入的节点会从头节点加入;超过阀值(默认8),单链表就会转为红黑树,提高检索速度;
HashMap扩容的条件是:当size大于threshold时,对HashMap进行扩容(threshold = 容量*加载因子)默认加载因子为0.75
扩容是是新建了一个HashMap的底层数组,而后调用transfer方法,将旧HashMap的全部元素添加到新的HashMap中(要重新计算元素在新的数组中的索引位置)。 扩容是一个相当耗时的操作,因为它需要重新计算这些元素在新的数组中的位置并进行复制处理。因此,我们在用HashMap的时,最好能提前预估下HashMap中元素的个数,这样有助于提高HashMap的性能。
HashTable和HashMap的区别
继承的父类不同
HashTable继承自Dictionary类,而HashMap继承自AbstractMap类;但两者都实现了Map接口;
线程安全不同
HashTable中的方法是Synchronized的,而HashMap是非Synchronized的;在多线程并发环境下,可以考虑使用HashTable,不需要为自己的方法实现同步;而HashMap就需要自己增加同步;
提供contains方法
HashMap提供containsValue和containsKey方法;
HashTable提供contains(等同于containsValue),containsValue和containsKey方法;
key和value是否允许null值
key和value都是对象,不能包含重复key,可以包含重复value;
HashTable中,key和vlaue都不允许出现null值;
HashMap中,key可以为null,仅有一个;可以有多个value为null值;当使用get()方法返回null值时,可能是没有null的key,也可能是key为null的值为null;所以在HashMap中不能有get()方法来判断是否存在某个键,而应该用containsKey()方法来判断;
容量及扩容方式不同
HashMap默认为16,要求底层数组的容量一定要为2的整数次幂,扩容为原来的2倍;
HashTable默认为11,扩容时容量为原来的2倍+1;