记得上次看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
- Hashtable
- ConcurrentHashMap
- 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>());