一、HashMap的定义
HashMap是基于哈希表的 Map 接口的实现,它存储的内容是键值对(key-value)映射,其中元素的排列顺序是不固定的。
此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。另外,HashMap是非线程安全的,也就是说在多线程的环境下,可能会存在问题;而Hashtable是线程安全的,但由于同步需要花时间,所以效率没有HashMap好,可以用Java5.0后线程安全的ConcurrentHashMap替代。日常开发中会广泛用到HashMap,我们可以很方便用之存取键值对。
Java 8.0后,HashMap的底层实现是数组+链表+红黑树。其中,当链表长度超过8时,会自动使用红黑树代替,红黑树的查找时间复杂度为O(logn)。
HashMap通过hashCode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap。
二、HashMap的继承关系和构造方法
1、HashMap继承关系
打开HashMap源代码,可以看到它是继承自 AbstractMap抽象类,并实现了Java集合的根接口Map,以及Cloneable和Serializable接口。
2、HashMap构造函数
三、HashMap常用方法
1、HashMap API:常用的方法有put(key,value),get(key),remove(key),size(),containKey(key).
2、使用举例:
import java.util.HashMap;
import java.util.Iterator;
public class HashMapTest13
{
public static void main(String[] args)
{
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("cn", "中国");
hashMap.put("jp", "日本");
hashMap.put("fr", "法国");
System.out.println("打印HashMap:"+hashMap);
System.out.println("********************");
System.out.println("cn:" + hashMap.get("cn"));
System.out.println(hashMap.containsKey("cn"));
System.out.println(hashMap.keySet());
System.out.println(hashMap.isEmpty());
System.out.println(hashMap.size());
hashMap.remove("cn");
System.out.println(hashMap);
System.out.println("********************");
//采用Iterator遍历HashMap
Iterator it = hashMap.keySet().iterator();
while(it.hasNext())
{
String key = (String)it.next();
System.out.println("key:" + key);
System.out.println("value:" + hashMap.get(key));
}
}
}
输出结果:
四、为什么ConcurrentHashMap和Hashtable都是线程安全,但是前者性能更高?
因为前者是用的分段锁(Lock),根据hash值锁住对应链表,当hash值不同时,使其能实现并行插入,效率更高;
而Hashtable是每个方法前都加上了synchronized关键字。
HashTable使用一把锁处理并发问题,当有多个线程访问时,需要多个线程竞争一把锁,导致阻塞
ConcurrentHashMap则使用分段,相当于把一个HashMap分成多个,然后每个部分分配一把锁,这样就可以支持多线程访问