Java 集合源码剖析系列02: Collection架构
1. 概要 :
首先,我们来看下 Collection的一些框架类的关系如下图:
image.png> 从图中我们可以看到,Collection 是一个接口,主要分支有list 和set接口,list 和set 接口有他们各自的实现类。通过接口进行抽象,接口允许我们操作集合时不必关注具体实现,从而达到“多态”。
为了方便我们抽象出了AbstractCollection抽象类,它实现了Collection中的绝大部分函数;这样,在Collection的实现类中,我们就可以通过继承AbstractCollection省去重复编码。AbstractList和 AbstractSet都继承于AbstractCollection,具体的List实现类继承于AbstractList,而Set的实现类则继承于AbstractSet。
而Collection中有一个iterator()函数,它的作用是返回一个Iterator接口。通常,我们通过Iterator迭代器来遍历集合。ListIterator是List接口所特有的,在List接口中,通过ListIterator()返回一个ListIterator对象。
接下来,我们分别对 Collection, List,set, AbstractCollection, AbstractList, AbstractSet, iterator, ListIterator 逐个介绍:
2. Collection简介 :
Collection 接口定义如下:
public interface Collection<E> extends Iterable<E> {}
Collection 作为集合的根接口,是高度抽象出来的集合,它定义了一组对象和它的子类需要实现的基本操作:比如 添加、删除、清空、遍历(读取)、是否为空、获取大小等等。
定义了的方法如下:
image.png
- 对集合的基础操作,比如 :
int size() // 获取元素个数
boolean isEmpty() // 集合里面数据元素是否为空
boolean contains(Object element) // 是否包含指定元素
Iterator<E> iterator() // 获取元素的迭代器
boolean add(E element) / /添加元素,成功时返回 true
boolean remove(Object element) // 删除元素,成功时返回 true
int hashCode(); // 返回集合元素的hashcode值
boolean equals(Object o); // object 对象与此集合元素进行相等性比较
- 对集合的基础操作,比如 :
- 对整个集合操作的一些方法,如下 :
boolean containsAll(Collection<?> c); //是否包含指定集合 c 的全部元素
boolean addAll(Collection<? extends E> c); //添加集合C中所有元素到本 集合中
boolean removeAll(Collection<?> c); 删除本集合中存在 c 集合中的元素
default boolean removeIf(Predicate<? super E> filter) {} 删除本集合中满足Predicat 集合要求中的元素
boolean retainAll(Collection<?> c) // 保留本集合中与 c 集合中两者共有的
void clear() // 删除所有元素
- 对整个集合操作的一些方法,如下 :
- 对转化为数组操作的方法有:
Object[] toArray(); // 返回一个包含集合中所有元素的数组
<T> T[] toArray(T[] a); // 返回一个包含集合中所有元素的数组,运行时根据集合元素的类型指定数组的类型
default <T> T[] toArray(IntFunction<T[]> generator) {} // 返回一个包含此collection中所有元素的数组,使用函数分配返回的数组。
- 对转化为数组操作的方法有:
- 还提供了从集合获取连续的或者并行流方法如下:
default Stream<E> stream() {}
default Stream<E> parallelStream() {}
- 还提供了从集合获取连续的或者并行流方法如下:
3. List 接口简介 :
List接口定义如下:
public interface List<E> extends Collection<E> {}
List 是一个元素有序的、可以重复、可以为 null 的集合
List 接口是继承于Collection接口,它自然就包含了Collection中的全部函数,除此之外新增的方法如下:
// 相比与Collection,List新增的API:
- 位置相关:List 和 数组一样,从 0 开始,我们可以根据元素在 list 中的位置进行操作,比如说 get, set, add, addAll, remove;
E get(int index);
E set(int index, E element);
void add(int index, E element);
boolean addAll(int index, Collection<? extends E> c);
E remove(int index);
- 位置相关:List 和 数组一样,从 0 开始,我们可以根据元素在 list 中的位置进行操作,比如说 get, set, add, addAll, remove;
-
2 . 搜索:查找list 中某个对象的位置,比如 indexOf, lastIndexOf;
int indexOf(Object o); // 返回 在这个列表中,指定元素第一次出现的索引
int lastIndexOf(Object o); -
3 . 迭代:使用 Iterator 的拓展版 迭代器 ListIterator 进行迭代操作;
ListIterator<E> listIterator();
ListIterator<E> listIterator(int index); - 范围性操作:使用 subList 方法对 list 进行任意范围的操作。
List<E> subList(int fromIndex, int toIndex);
- 范围性操作:使用 subList 方法对 list 进行任意范围的操作。
4. Set 接口简介 :
Set 接口定义如下:
public interface Set<E> extends Collection<E> {}
- Set 接口是一个继承于Collection的接口,Set是一个没有重复元素的集合,关于API方面。Set的API和Collection基本一样。
4. AbstractCollection 简介 :
AbstractCollection的定义如下:
public abstract class AbstractCollection<E> implements Collection<E> {}
------抽象类可以不用实现接口的全部方法
- AbstractCollection 是 Java 集合框架中 Collection 接口 的一个直接实现类,它实现了Collection接口中的大部分函数。从而方便其它类实现Collection,比如ArrayList、LinkedList等(通过继承AbstractCollection就已经实现了大部分的接口了)。
........
AbstractCollection 实现Collection 的api 有:
public boolean contains(Object o) {}
public Object[] toArray() {}
public <T> T[] toArray(T[] a) {}
public boolean add(E e) {}
public boolean remove(Object o) {}
public boolean containsAll(Collection<?> c) {}
public boolean addAll(Collection<? extends E> c) {}
public boolean removeAll(Collection<?> c) {}
public boolean retainAll(Collection<?> c) {}
public void clear() {}
- AbstractCollection 是 Java 集合框架中 Collection 接口 的一个直接实现类,它实现了Collection接口中的大部分函数。从而方便其它类实现Collection,比如ArrayList、LinkedList等(通过继承AbstractCollection就已经实现了大部分的接口了)。
5. AbstractList 简介 :
AbstractList 的定义如下:
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {}
- AbstractList是一个继承于AbstractCollection,所以AbstractList 实现AbstractCollection 中的抽象函数: iterator() 和 size(),如果子类想要能够修改元素,还需要重写 add(), set(), remove() 方法,否则会报 UnsupportedOperationException 错。
- AbstractList 内部已经提供了 Iterator, ListIterator 迭代器的实现类,分别为 Itr, ListItr,
6. AbstractSet简介 :
AbstractSet的定义如下:
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {}
- AbstractSet是一个继承于AbstractCollection,由于Set接口和Collection接口中的API完全一样,Set也就没有自己单独的API,AbstractSet 抽象类中实现部分函数。
7. Iterator
Iterator的定义如下:
public interface Iterator<E> {}
-
1 . Iterator是一个接口,它是集合的迭代器。集合可以通过Iterator去遍历集合中的元素。Iterator提供的API接口,包括:是否存在下一个元素、获取下一个元素、删除当前元素。
主要函数如下:
boolean hasNext(); // 是否存在未遍历元素
E next(); // 返回下一个元素
default void remove() // 移除一个元素
default void forEachRemaining(Consumer<? super E> action) {} /// 流式遍历。遍历每个元素,并对其执行相应的择取操作。
image.png
- Iterator遍历Collection时,是fail-fast机制的;
什么是fail-fast机制?
当某一个线程遍历list的过程中,list的内容被另外一个线程所改变了;就会抛出ConcurrentModificationException异常,产生fail-fast事件。
- Iterator遍历Collection时,是fail-fast机制的;
8 . ListIterator
ListIterator的定义如下:
public interface ListIterator<E> extends Iterator<E> {}
ListIterator是一个继承于Iterator的接口,它是队列迭代器。专门用于便利List,能提供向前/向后遍历。相比于Iterator,它新增了添加、是否存在上一个元素、获取上一个元素等等API接口。
主要api 函数如下:
image.png
.
.
.
.