HashMap & HashSet 知识回顾

in with 0 comment

记得上次看HashMap和HashSet源码已经是很久之前的事情了,依稀记得看的是1.6的内容,这几天不忙的时候,又点进去1.8去看了看做一个知识回顾。

底层实现

HashMap底层是一个Entry<Key,Value>的单例键值对的集合,并对Key做了hash,实现HashMap的put/get操作; HashSet的底层是由HashMap来实现的,当做add操作的时候,实际操作是在HashMap中put了一个 <Key,EmptyObject> 的node。

遍历

HashMap的遍历推荐使用forEach或者通过entrySet()或者Entry的Set集合,减少多余操作。

HashMap<String, String> map = new HashMap();
map.put("123", "321");

map.forEach((k, v) -> System.out.println(k + v));

Set<Entry<String, String>> set = map.entrySet();
set.forEach(entry -> System.out.println(entry.getKey() + entry.getValue()));

线程安全

HashMap是线程不安全的,所以HashSet当然也是线程不安全的,其原因在于HashMap的put实现,当由两个线程AB同时进行写入数据时,A和B先后获取了map的链头,当A插入数据后更新了链头数据,而B拿到的还是旧的链头数据,B插入数据之后照常更新链头致使A的数据丢失。

线程安全的Map

  1. Hashtable
  2. ConcurrentHashMap
  3. Synchronized Map
//Hashtable
Map<String, String> hashtable = new Hashtable<>();

//ConcurrentHashMap
Map<String, String> concurrentHashMap = new ConcurrentHashMap<>();

//synchronizedMap
Map<String, String> synchronizedHashMap = Collections.synchronizedMap(new HashMap<String, String>());

Key 可以是 null