1. Java集合总体框架
Java集合中List,Set以及Map等集合体系详解
Java 集合系列01之 总体框架
Java集合工具包在java.util.*
下,他们的继承关系如下图所示
Java集合主要可以划分为4个部分:List
列表、Set
集合、Map
映射、工具类(Iterator
迭代器、Enumeration
枚举类、Arrays
和Collections
)
List
,Set
,Map
都是接口,前两个继承至Collection
接口,Map
为独立接口Set
下有HashSet
,LinkedHashSet
,TreeSet
List
下有ArrayList
,Vector
,LinkedList
Map
下有Hashtable
,LinkedHashMap
,HashMap
,TreeMapCollection
接口下还有个Queue
接口,有PriorityQueue
类
1.1 Collection
接口
通过他的注释我们可以知道很多信息
Collection
是一个接口,是高度抽象出来的集合,包含了集合的基本操作和属性
Collection
包含了List
和Set
两大分支
-
List是一个有序的队列,每一个元素都有它的索引,第一个元素的索引值是0,List的实现类有LinkedList, ArrayList, Vector, Stack。
-
Set是一个不允许有重复元素的集合,Set的实现类有HastSet和TreeSet。HashSet依赖于HashMap,它实际上是通过HashMap实现的;TreeSet依赖于TreeMap,它实际上是通过TreeMap实现的
1⃣️ List
接口
Java 集合框架中最常使用的几种 List
实现类是 ArrayList
,LinkedList
和 Vector
。
在各种 List 中,最好的做法是以 ArrayList
作为默认选择。 当插入、删除频繁时,使用 LinkedList
;
(因为LinkedList
底层是用链表实现的,而ArrayList
底层是数组)
Vector
总是比 ArrayList
慢,所以要尽量避免使用它
(因为实现了同步控制)
在List
中除了继承Collection
中的一些方法,还提供了以下操作
① 位置相关:List
和 数组一样,都是从 0 开始,我们可以根据元素在 list
中的位置进行操作,比如说
get
, set
, add
, addAll
, remove
;
② 搜索:从 list
中查找某个对象的位置,比如 indexOf
, lastIndexOf
;
③ 迭代:使用 Iterator
的拓展版迭代器 ListIterator
进行迭代操作;
④ 范围性操作:使用 subList
方法对 list
进行任意范围的操作
其中在List
接口中定以了 ListIterator listIterator()
方法用来返回一个listIterator()
,listIterator()
更强大它可以双向遍历,同时还允许进行add
,set
,remove
等操作
2⃣️ AbstractCollection
抽象类
AbstractCollection
是对Collection
接口的直接实现类(是一个抽象类),Collection
下的大多数子类都要继承AbstractCollection
,他实现了一些方法,也定义了一些抽象方法留给子类实现
注意:
在AbstractCollection
中不支持添加单个元素,所以直接调用add(E)
方法会报错,如果子类是可添加的数据结构,需要自己实现这些方法
public boolean add(E object) {
throw new UnsupportedOperationException();
}
这样设计主要是因为如果你想修改一个不可变的集合时,抛出 UnsupportedOperationException
是标准的行为,比如 当你用 Collections.unmodifiableXXX()
方法对某个集合进行处理后,再调用这个集合的 修改方法(add,remove,set…
),都会报这个错
3⃣️ AbstractList
抽象类
AbstractList
继承自 AbstractCollection
抽象类,实现了 List
接口 ,是 ArrayList
和 AbstractSequentiaList
的父类。它实现了 List
的一些位置相关操作,是第一个实现随机访问方法的集合类,但不支持添加和替换。还是默认不支持add(),set(),remove()
操作
在AbstractList
中实现了ListIterator
和Iterator
4⃣️ Queue
接口
Queue接口与List、Set同一级别,都是继承了Collection接口。
看图你会发现,LinkedList既可以实现Queue接口,也可以实现List接口.只不过呢, LinkedList实现了Queue接口。Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法 了,而不能直接访问 LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用
5⃣️ ArrayList
/ Vector
/ LinkedList
ArrayList
优点: 底层数据结构是数组,查询快,增删慢。
缺点: 线程不安全,效率高
Vector
优点: 底层数据结构是数组,查询快,增删慢。
缺点: 线程安全,效率低
LinkedList
优点: 底层数据结构是链表,查询慢,增删快。
缺点: 线程不安全,效率高
1.2 Map
接口
Map
是一个映射接口,即key-value
键值对。Map
中的每一个元素包含“一个key
”和“key
对应的value
”。
AbstractMap
是个抽象类,它实现了Map
接口中的大部分API。而HashMap
,TreeMap
,WeakHashMap
都是继承于AbstractMap
TreeMap
是有序的,HashMap
和HashTable
是无序的。Hashtable
的方法是同步的,HashMap
的方法不是同步的。这是两者最主要的区别。
这就意味着:
Hashtable
是线程安全的,HashMap
不是线程安全的。HashMap
效率较高,Hashtable
效率较低。如果对同步性或与遗留代码的兼容性没有任何要求,建议使用HashMap
。 查看Hashtable
的源代码就可以发现,除构造函数外,Hashtable
的所有public
方法声明中都有synchronized
关键字,而HashMap
的源码中则没有。Hashtable
不允许null
值,HashMap
允许null
值(key和value都允许)- 父类不同:
Hashtable
的父类是Dictionary
,HashMap
的父类是AbstractMap
1.3 Iterable
接口
Collection
继承了 Iterable< E >
接口,Iterable
接口内只有一个 iterator
方法,返回一个 Iterator
迭代器
1.4 Iterator
接口
它是遍历集合的工具,即我们通常通过Iterator迭代器来遍历集合。我们说Collection依赖于Iterator,是因为Collection的实现类都要实现iterator()函数,返回一个Iterator对象。
通过Iterable定义的iterator()方法可以拿到iterator对象
同时foreach遍历集合的底层也是通过迭代器实现的,所以迭代器可以说是集合中必不可少的一部分了
2. 源码分析
2.1 为什么要阅读源码
2.2 如何阅读源码
- 掌握用法
- 看继承结构
- 看构造方法
- 看常用方法
2.3 学习目录
ArrayList源码分析
Arrays.asList分析
LinkedList源码分析
CopyOnWriteArrayList源码分析
PriorityQueue源码分析
迭代器详解
Map详解
HashMap源码分析
HashMap的几个难点
LinkedHashMap源码分析
ConcurrentHashMap & HashTable