集合框架学习(持续更新)
Java集合框架总体结构图
Collection 接口
定义集合基本方法
1
|
int size();
|
AbstractCollection 抽象类
实现Collection接口中部分方法
boolean isEmpty()
校验集合是否为空
boolean contains(Object o)
校验集合是否包含o元素,该方法中会使用到迭代器iterator()方法
Object[] toArray()
把集合转换成数组,该方法中会使用到迭代器iterator()方法,该方法的实现有必要看一下。在初始化数组时,如果长度不够,是按照cap + (cap >> 1) + 1的方式增加数组长度的,如果长度过长,再使用Arrays.copyOf(T[] original, int newLength)方法重置数组长度
T[] toArray(T[] a)
暂定解释,这个方法有点没太理清楚
boolean add(E e)
直接抛出UnsupportedOperationException异常,默认不支持该操作,后续需要重写该方法
boolean remove(Object o)
使用迭代器,以o是否为null分别做remove操作,如果有remove操作,返回true
boolean containsAll(Collection<?> c)
调用boolean contains(Object o)方法循环遍历,仅有集合中包含c所有值,才返回true
boolean addAll(Collection<? extends E> c)
调用boolean add(E e)方法,只要新增成功一次就返回true
boolean removeAll(Collection<?> c)
使用迭代器,循环遍历当前集合,调用boolean contains(Object o)判断c集合是否包含当前元素,如果包含,则使用迭代器的remove()方法进行删除
boolean retainAll(Collection<?> c)
与boolean removeAll(Collection<?> c)方法类似,只不过是删去c集合中不包含的元素
void clear()
使用迭代器,循环便利当前集合,使用迭代器的remove()方法依次删除元素
String toString()
使用迭代器,循环遍历集合元素,通过StringBuilder组合元素
List 接口
继承了Collection接口,List接口又另外定义了一些方法
1
|
int size();
|
AbstractList 抽象类
实现List接口,继承AbstractCollection抽象类
boolean add(E e)
调用add(int index, E element)方法,在集合末尾增加元素,只要增加成功,就返回true
abstract public E get(int index)
待实现
E set(int index, E element)
直接抛出UnsupportedOperationException异常,默认不支持该操作,后续需要重写该方法
void add(int index, E element)
直接抛出UnsupportedOperationException异常,默认不支持该操作,后续需要重写该方法
E remove(int index)
直接抛出UnsupportedOperationException异常,默认不支持该操作,后续需要重写该方法
int indexOf(Object o)
获取listIterator()返回的ListIterator迭代器根据o是否为null分别做处理,如果按从前往后顺序集合中有o这个元素,则返回o元素的下标,否则返回-1
int lastIndexOf(Object o)
跟int indexOf(Object o)方法类似,获取listIterator()返回的ListIterator迭代器根据o是否为null分别做处理,如果按从后往前顺序集合中有o这个元素,则返回o元素的下标,否则返回-1
void clear()
调用removeRange(int fromIndex, int toIndex)方法,删去从0到集合末尾的所有元素
boolean addAll(int index, Collection<? extends E> c)
先校验index是否越界,然后循环在数组index的位置依次插入c中元素,只要插入成功一条记录就设置返回值为true
Iterator iterator()
返回new Itr()
ListIterator listIterator()
返回listIterator(0)方法
ListIterator listIterator(final int index)
先校验index是否越界,然后返回new ListItr(index)
List subList(int fromIndex, int toIndex)
根据当前集合是否是RandomAccess接口的实现类,如果是,则返回RandomAccessSubList类型fromIndex,toIndex之间的子集合;如果不是,则返回SubList类型fromIndex,toIndex之间的子集合
boolean equals(Object o)
当前集合和o集合(假设o是List接口的实现类)分别根据ListIterator<E> listIterator()方法获取迭代器,然后元素依次比较,直至出现不相同的为止。完全相同返回true,否则返回false
int hashCode()
返回当前集合的hashCode值,代码有必要直接贴出来
1
|
public int hashCode() {
|
AbstractList$Itr 内部类
直接贴代码介绍
1
|
private class Itr implements Iterator<E> {
|
AbstractList$ListItr 内部类
1
|
// 可以指定从集合中哪个位置开始的迭代器
|
AbstractList/SubList AbstractList中非public的类
继承AbstractList抽象类,构造方法中有fromIndex和toIndex入参以便重新设计子集合,该类中把AbstractList没有实现的方法都具体实现了一下,没有什么特别难理解的地方,就不单独贴出来具体代码
AbstractList/RandomAccessSubList AbstractList中非public的类
继承SubList类,实现RandomAccess接口,就重写了一下List<E> subList(int fromIndex, int toIndex)这个方法,返回的子集合是RandomAccessSubList类型
ArrayList 类
继承AbstractList抽象类,实现List,RandomAccess,Cloneable,Serializable接口,该类中有2个属性
1
|
private transient Object[] elementData; //ArrayList的实现方式其实还是用数组的方式进行的
|
ArrayList(int initialCapacity) 构造方法
根据传入的集合长度,初始化一个等长的elementData
ArrayList() 构造方法
默认初始化一个长度为10的elementData
ArrayList(Collection<? extends E> c) 构造方法
c集合调用toArray()方法返回的数组赋值到elementData中,并获取elementData的长度设置到size中
void trimToSize()
把集合的长度缩短至集合elementData.length,也就是把集合末尾未使用到的位置给移除掉。modCount要自增一次,modCount是AbstractList中的属性,用来记录集合变更的次数
void ensureCapacity(int minCapacity)
对ArrayList实例进行扩容,以够容纳minCapacity这么多元素。扩容时会让modCount自增一次。
1
|
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; //一些 VMs在数组里保留字头,试图分配更大数组时可能导致OutOfMemoryError:被请求数组的size超出VM界限。
|
int size()
直接返回size属性
boolean isEmpty()
返回size == 0
int indexOf(Object o)
在elementData从前往后查找o元素第一次出现的位置,如果没找到,则返回-1
boolean contains(Object o)
调用indexOf(Object o)方法,判断o元素第一次出现的位置是否大于0,大于0也就意味着集合中包含断o元素
int lastIndexOf(Object o)
在elementData从后往前查找o元素第一次出现的位置,如果没找到,则返回-1
Object clone()
调用父类的clone()方法,并重置新集合的modCount为零。该克隆为浅克隆
Object[] toArray()
把elementData集合扩展到size长度并返回
T[] toArray(T[] a)
暂定解释,这个方法有点没太理清楚
E get(int index)
先校验一遍index是否大于size(没有校验是否小于0,看注释的意思是,如果index小于0,在该校验前就会抛出ArrayIndexOutOfBoundsException),然后直接获取elementData[index]
set(int index, E element)
先校验一遍index是否小于size,然后elementData[index] = element,返回index位置原来的元素
boolean add(E e)
先调用ensureCapacityInternal(int minCapacity)方法(入参为size+1)对elementData数组进行扩容,然后再进行elementData[size++] = e操作,最终返回true
void add(int index, E element)
1
|
public void add(int index, E element) {
|
E remove(int index)
1
|
public E remove(int index) {
|
boolean remove(Object o)
先for循环找到o元素的下标,然后使用remove(int index)类似的逻辑做删除操作
void clear()
先modCount++设置集合修改次数+1,然后for循环elementData,依次设置每个元素都为null,最终设置size为0
boolean addAll(Collection<? extends E> c)
放上代码更容易理解
1
|
public boolean addAll(Collection<? extends E> c) {
|
boolean addAll(int index, Collection<? extends E> c)
放上代码更容易理解
1
|
public boolean addAll(int index, Collection<? extends E> c) {
|
##### boolean removeAll(Collection<?> c)
返回batchRemove(c, false)
boolean retainAll(Collection<?> c)
返回batchRemove(c, true)
1
|
private boolean batchRemove(Collection<?> c, boolean complement) {
|
private void writeObject(java.io.ObjectOutputStream s)
实现Serializable接口是需要有writeObject方法的实现的,由于Object方法默认就有writeObject方法的实现,所以Serializable接口中未定义抽象方法,但如果想自定义序列化方法,则需要重新该方法
private void readObject(java.io.ObjectInputStream s)
实现Serializable接口是需要有readObject方法的实现的,由于Object方法默认就有readObject方法的实现,所以Serializable接口中未定义抽象方法,但如果想自定义序列化方法,则需要重新该方法
ListIterator listIterator(int index)
校验index是否是0到size之间的,然后返回new ListItr(index)
ListIterator listIterator()
返回new ListItr(0)
Iterator iterator()
返回new Itr()
List subList(int fromIndex, int toIndex)
先校验fromIndex,toIndex是否符合规则,然后返回new SubList(this, 0, fromIndex, toIndex)
ArrayList$Itr 内部类
跟AbstractList$Itr类似,作用也一样,不贴代码了
ArrayList$ListItr 内部类
跟AbstractList$ListItr类似,作用也一样,不贴代码了
ArrayList/SubList ArrayList中非public的类
继承AbstractList抽象类,实现RandomAccess接口,构造方法中有fromIndex和toIndex入参以便重新设计子集合,该类中把AbstractList没有实现的方法都具体实现了一下,没有什么特别难理解的地方,就不单独贴出来具体代码
Vector 类
继承AbstractList抽象类,实现List, RandomAccess, Cloneable,Serializable接口
Vector跟ArrayList相比,Vector是线程安全的,所有可用方法都使用了synchronized进行了修饰
Vector有如下3个属性
1
|
protected Object[] elementData; // Vector跟ArrayList类似,底层也是使用数组实现的
|
Vector(int initialCapacity, int capacityIncrement) 构造方法
根据传入的参数initialCapacity,初始化等长的Object数组——elementData,同时设置自动扩容的长度为capacityIncrement
Vector(int initialCapacity) 构造方法
根据传入的参数,初始化等长的Object数组——elementData,设置自动扩容的长度capacityIncrement为0
Vector() 构造方法
初始化一个长度为10的Object数组——elementData,设置自动扩容的长度capacityIncrement为0
Vector(Collection<? extends E> c) 构造方法
c集合调用toArray()方法返回的数组设置到elementData中,长度设置到elementCount中
void copyInto(Object[] anArray)
将当前Vector实例复制到anArray中
void trimToSize()
把集合的长度缩短至集合elementData.length,也就是把集合末尾未使用到的位置给移除掉。modCount要自增一次,modCount是AbstractList中的属性,用来记录集合变更的次数
void ensureCapacity(int minCapacity)
对Vector实例进行扩容,以够容纳minCapacity这么多元素。扩容时会让modCount自增一次。一下代码跟ArrayList.ensureCapacity(int minCapacity)类似,唯一不同是Vector的扩容涉及到capacityIncrement属性
1
|
private void grow(int minCapacity) {
|
##### void setSize(int newSize)
如果newSize大于当前数组长度,则扩容,如果小于等于当前长度,则把newSize之外的数组元素置为null,再把elementCount设置为newSize,相当于缩容
int capacity()
返回elementData.length,是数组实际长度
int size()
返回elementCount,是Vector可容纳元素的数量,即设置的长度
##### boolean isEmpty()
返回elementCount == 0
Enumeration elements()
返回Enumeration接口的实现类(枚举类),类似于迭代器。在使用上更优先使用Iterator接口
int indexOf(Object o, int index)
从index位置开始,查找o在Vector实例中所在位置的下标
indexOf(Object o)
和int indexOf(Object o, int index)方法是重载方法,返回indexOf(o, 0)
contains(Object o)
校验indexOf(o, 0)方法返回的下标值是否大于0
lastIndexOf(Object o, int index)
从index到0的范围内,从后往前查找o元素所在位置的小标
lastIndexOf(Object o)
返回lastIndexOf(o, elementCount-1)
E elementAt(int index)
返回index位置的元素
E firstElement()
返回数组中的第一个元素
E lastElement()
返回数组中的最后一个元素,最后元素指的是下标为elementCount - 1位置的元素
void setElementAt(E obj, int index)
重新设置index位置的元素为obj
void removeElementAt(int index)
modCount自增,如果index非数组中的最后一个元素,则把数组中index后的元素整体前移一个位置,把index位置的元素挤掉,然后设置elementCount自减,设置elementCount位置的元素为null
void insertElementAt(E obj, int index)
modCount自增,把elementCount + 1当做Vector实例最小长度进行扩容,然后对index后的元素整体后移一位,再设置index位置的元素为obj,最后elementCount自增
void addElement(E obj)
modCount自增,把elementCount + 1当做Vector实例最小长度进行扩容,设置elementCount位置的元素为obj,最后elementCount自增
boolean removeElement(Object obj)
modCount自增,调用indexOf(Object o)方法查找obj元素的下标,再调用removeElementAt(int index)方法进行删除
void removeAllElements()
modCount自增,for循环elementData数组,设置数组元素全为null,最后设置elementCount为0
Object clone()
调用父类clone()方法获得一个新Vector实例v,设置v的elementData为Arrays.copyOf(elementData, elementCount),v的modCount为0,最终返回v
Object[] toArray()
直接返回Arrays.copyOf(elementData, elementCount)
T[] toArray(T[] a)
暂定解释,这个方法有点没太理清楚
E get(int index)
返回elementData数组中index位置的元素,和elementAt(int index)方法其实是一样的
E set(int index, E element)
和setElementAt(E obj, int index)方法类似,只不过set(int index, E element)方法返回index位置的旧值
boolean add(E e)
和addElement(E obj)方法类似,只不过add(E e)会返回true
boolean remove(Object o)
直接调用removeElement(o)
void add(int index, E element)
直接调用insertElementAt(element, index)
E remove(int index)
和removeElementAt(int index)类似,只不过会返回index位置的旧值
void clear()
返回removeAllElements()
boolean containsAll(Collection<?> c)
调用父类的containsAll(c)方法
boolean addAll(Collection<? extends E> c)
modCount自增,把elementCount + numNew当做集合最小长度进行扩容,在elementData数组后接上c.toArray获取到的集合,elementCount增加到elementCount + numNew,最终返回numNew != 0
boolean removeAll(Collection<?> c)
调用父类的removeAll(c)方法
boolean retainAll(Collection<?> c)
调用父类的retainAll(c)方法
addAll(int index, Collection<? extends E> c)
modCount自增,数组扩容,对elementData从index位置开始右移,再把c集合的元素放置其中,最后设置elementCount数量,返回numNew != 0
boolean equals(Object o)
调用父类的equals(o)方法
int hashCode()
调用父类的hashCode方法
String toString()
调用父类的toString方法
List subList(int fromIndex, int toIndex)
使用Collections工具类的synchronizedList(List<T> list, Object mutex)方法
1
|
public synchronized List<E> subList(int fromIndex, int toIndex) {
|
void removeRange(int fromIndex, int toIndex)
把elementData中fromIndex-toIndex之间的元素移除,计算新的elementCount,设置elementData末尾所有的元素为null
ListIterator listIterator(int index)
返回new ListItr(index)
ListIterator listIterator()
返回new ListItr(0)
Iterator iterator()
返回new Itr()
Vector$Itr 内部类
跟父类的类似,不做解释
Vector$ListItr 内部类
跟父类的类似,不做解释
Stack 类
该类是继承自Vector类的,所以Vector类中的方法Stack都可以使用。该类称之为堆栈类,可以使用堆栈的方法进行操作
E push(E item)
向elementData的末尾增加一个item元素,调用addElement(item)方法实现的,最终返回item
E peek()
获取elementData中最后一个元素
E pop()
获取elementData中最后一个元素,并将最后一个元素删去
empty()
返回size() == 0
int search(Object o)
查找o元素距离elementData末尾的位置
AbstractSequentialList 抽象类
继承自AbstractList抽象类,对AbstractList中的几个抽象方法进行了实现
E get(int index)
使用ListIterator获取从index位置开始的迭代器,返回index位置的元素值
E set(int index, E element)
使用ListIterator获取从index位置开始的迭代器,设置当前位置为新值element,最终返回旧值
void add(int index, E element)
使用ListIterator获取从index位置开始的迭代器,在该位置后直接插入element元素
E remove(int index)
使用ListIterator获取从index位置开始的迭代器,对该位置元素进行删除,最后返回该元素值
boolean addAll(int index, Collection<? extends E> c)
使用ListIterator获取从index位置开始的迭代器,再获取c集合对应迭代器,依次往当前集合的index位置后面加入元素。只要加入了元素,就返回true
Iterator iterator()
返回listIterator()
abstract ListIterator listIterator(int index)
待实现
Deque 接口
继承Queue接口,对Queue接口方法进行补充。一个线性 collection,支持在两端插入和移除元素
1
|
void addFirst(E e);
|
LinkedList 类
继承AbstractSequentialList抽象类,实现List, Deque, Cloneable, Serializable接口。该类中有一下3个属性
1
|
transient int size = 0; // 集合长度
|
LinkedList() 构造函数
空的构造函数
LinkedList(Collection<? extends E> c) 构造函数
把c集合转为LinkedList集合
LinkedList$Node 内部类
该内部类定义了LinkedList中各个元素,Node中设置有3个属性
1
|
E item; // 当前元素
|
LinkedList中比较重要的几个非public方法
1
|
private void linkFirst(E e) {
|
E getFirst()
获取first元素,返回first.item
E getLast()
获取last元素,返回last.item
E removeFirst()
获取first元素,调用unlinkFirst(f)方法删去第一个元素
E removeLast()
获取last元素,调用unlinkLast(l)方法删去最后一个元素
addFirst(E e)
调用linkFirst(e)方法在集合头插入元素
void addLast(E e)
调用linkLast(e)方法在集合尾插入元素
boolean contains(Object o)
返回indexOf(o) != -1
int size()
返回size
boolean add(E e)
调用linkLast(e)方法在集合尾插入元素,返回true
boolean remove(Object o)
循环遍历集合,找到集合中所有的o元素,调用unlink(x)方法进行删除,只要删除不止一个元素,就返回true
boolean addAll(Collection<? extends E> c)
返回addAll(size, c),在集合末尾新增c集合
boolean addAll(int index, Collection<? extends E> c)
先校验index是否合法,需要大于等于零,小于等于size。c调用toArray()方法获得数组a,如果数组长度等于零,则直接返回false。获取index位置的Node为succ,获取succ.pred的Node为pred。再循环a数组,在循环中Node<E> newNode = new Node<>(pred, e, null),如果pred为空,说明当前集合是空的,所以设置first为newNode,如果pred不为空,则设置pred.next为newNode,就是设置上一个Node中的next为当前newNode。循环中最后设置pred为newNode,以便于下次循环使用。循环结束后如果succ为空,意味着原集合为空,则需要设置last为循环中的最后一个Node,如果succ不为空,则设置pred.next为succ,succ.prev为pred。最后size+numNew,modCount+1,并返回true
void clear()
循环当前集合,设置每一个Node中的item、next、prev为空,设置集合中的first、last为空,size为0,modCount+1
E get(int index)
校验index合法性,获取index所在位置的Node,返回该Node中的item
set(int index, E element)
校验index合法性,获取index所在位置的Node,获取该Node的item为oldVal,设置该Node的item值为element,最后返回oldVal
void add(int index, E element)
校验index合法性,如果index为集合末尾,则调用linkLast(element)增加元素,如果index非集合末尾,则调用linkBefore(element, node(index))插入元素
E remove(int index)
校验index合法性,调用unlink(node(index))方法删除元素
int indexOf(Object o)
从前往后循环当前集合,返回o出现的第一个位置的下标,如果没找到则返回-1
int lastIndexOf(Object o)
从后往前循环当前集合,返回o出现的第一个位置的下标,如果没找到则返回-1
E peek()
获取first的Node为f,如果f为空,则返回null,否则返回f.item
E element()
返回getFirst()方法的结果
E poll()
获取first的Node为f,如果f为空,则返回null,否则返回unlinkFirst(f)方法的结果,相当于返回第一个元素并删去第一个元素
E remove()
返回removeFirst()方法的结果
boolean offer(E e)
返回add(e)
boolean offerFirst(E e)
调用addFirst(e)方法,然后返回true
boolean offerLast(E e)
调用addLast(e)方法,然后返回true
E peekFirst()
获取first的Node为f,如果f为空,则返回null,否则返回f.item
E peekLast()
获取last的Node为l,如果l为空,则返回null,否则返回l.item`
E pollFirst()
获取first的Node为f,如果f为空,则返回null,否则返回unlinkFirst(f)
E pollLast()
获取last的Node为l,如果l为空,则返回null,否则返回unlinkLast(l)`
void push(E e)
调用addFirst(e)方法
E pop()
调用removeFirst()方法
boolean removeFirstOccurrence(Object o)
调用remove(o)方法
boolean removeLastOccurrence(Object o)
从后往前遍历集合,在集合中查找o元素第一次出现对应的Node为x,对x调用unlink(x)方法进行删除,并返回true,如果没找到o元素,则返回false
ListIterator listIterator(int index)
先校验index的合法性,然后返回new ListItr(index)迭代器
LinkedList$ListItr 内部类
跟其他集合的ListItr内部类类似
LinkedList$DescendingIterator内部类
跟ListItr相比,该内部类是一个反序的Iterator,该类中有一个属性ListItr itr = new ListItr(size()),类中的hasNext()方法返回的是itr.hasPrevious()
Object clone()
实现浅克隆,设置克隆的LinkedList的fisrt = last = null,size = 0,modCount = 0,然后循环当前集合,依次调用add方法加入到克隆集合中,最后返回
Object[] toArray()
新建一个数组,长度为size,循环当前集合Node为x,数组中依次新增x.item,最后返回该数组
T[] toArray(T[] a)
暂定解释,这个方法有点没太理清楚
Queue 接口
继承Collection接口,提供跟队列相关的抽象方法
1
|
boolean add(E e);
|
AbstractQueue 抽象类
继承AbstractCollection抽象类,实现Queue接口,该类中对方法的实现都比较抽象,一般都需要具体的类对方法进行重新
boolean add(E e)
如果调用offer(e)方法返回true,则该方法返回true,否则抛异常
E remove()
调用poll()方法返回对象x,如果x不为null,则返回x,否则抛异常
E element()
调用peek()方法返回对象x,如果x不为null,则返回x,否则抛异常
void clear()
不好描述,直接看代码吧
1
|
public void clear() {
|
boolean addAll(Collection<? extends E> c)
如果c为null,抛异常,如果c==this,抛异常,然后循环c,调用add(e)方法进行插入,最终返回集合是否新增了c
PriorityQueue 类
优先级队列,继承AbstractQueue抽象类,实现Serializable接口,该集合的实现是以完全二叉树的形式进行存储的
以下是该类中的部分属性
1
|
private static final int DEFAULT_INITIAL_CAPACITY = 11; // PriorityQueue类默认自增长度
|
先列一下该类中的私有方法,因为构造方法中也很可能用到这些私有方法
1
|
// 如果c集合是PriorityQueue类的子类的话,通过该类进行初始化 |

