本文以JDK 1.8为例,包路径rt.jar java.util.lang
容器 | 实现方式 | 重复对象 | 空元素 | 顺序 | 使用场景 |
List | 实现接口Collection | 可以有重复对象 | 可以插入多个空元素 | 有序容器 | 经常访问元素,使用list |
Set | 实现接口Collection | 不容许对象重复 | 只能一个空元素 | 无序容器 | 插入数据唯一使用set |
Map | 接口 | 不容许对象重复,键值对 | 只有一个null | 有序容器(默认升序) | 键值存储用map |
比较 | 常用 | 线程安全,方法用Synchonized修饰 | 顺序存储 |
Set | HashSet | ConcurrentHashSet | LinkedHashSet |
Map | HashMap | ConcurrentHashMap | LinkedHashMap |
1 HashMap原理
在bucket中存储键对象和值对象,作为Map.Entry。使用put(key,value)存储对象到HashMap中,使用get(key)从HashMap中获取对象。当我们给put方法传递键值的时候,我们先对键调用HashCode()方法,返回的HashCode用于找到bucket位置存储Entry对象。
Hash碰撞:两个键的HashCode相同即发生了Hash碰撞,HashMap是如何处理碰撞的呢,首先通过HashCode找到bucket位置,然后调用keys.equals()方法去找到LinkedList中正确的节点,最终找到要找的值对象。
HashMap只容许一条记录的键为null,容许多条记录的值为null。
2 ConcurrentHashMap原理
线程安全。为什么提到是线程安全呢?因为该类中涉及到数据操作的时候都使用了关键字synchronized修饰。
ConcurrentHashMap使用了锁分离技术。内部使用段Segment来分割,每个段其实就是一个小的Hashtable,他们有自己的锁。只要多个修改操作发生在不同的段上,这些操作就可以并发进行。有些方法需要跨段,比如Size(),containsValue(),执行时需要锁定整个表,而不是仅仅某个段,这时需要按顺序锁定所有段,操作完毕后,又按顺序释放所有段的锁。
3 ArrayList原理