0
点赞
收藏
分享

微信扫一扫

JDK源码——Collection,List,Map,Queue, Deque等接口类


摘要

本文主要是介绍在JDK中的常见的接口的说明。

Collection

而 Collection 接口又是集合层次中的根接口,最常用的 List 和 Set 接口都继承自它。它们的继承结构如下(常用部分):

size(): 集合中包含的元素个数;

isEmpty(): 集合是否为空;

contains(Object): 集合中是否包含某个对象;

iterator(): 返回该集合的迭代器,用于(顺序)遍历该集合;

Object[] toArray(): 将集合中的元素“拷贝”到一个 Object 数组中;

T[] toArray(T[] a): 作用同 5.1,区别在于该方法可以指定数组的类型(这两个方法用于集合与数组之间的转换);

add(E): 添加元素;

remove(Object): 移除元素;

containsAll(Collection<?>): 判断该集合是否包含另一个集合;

addAll(Collection<? extends E>): 将另一个集合的所有元素都添加到该集合中;

removeAll(Collection<?>): 从该集合中移除指定集合的所有元素;

removeIf(Predicate<? super E>): 从该集合中移除满足指定条件的元素,其中 Predicate 是 JDK 1.8 引入的函数式操作,即传入的参数是一个方法;

retainAll(Collection<?>): 保留指定集合中的元素,即移除所有未包含在指定集合中的元素;

clear(): 清空集合;

equals(Object): 比较该集合与指定的对象是否相等;

hashCode(): 返回该集合的哈希值,注意重写 equals 方法时必须要重写该方法,以满足 Object.hashCode 方法的规定。

spliterator(): 可分割迭代器,用于并行遍历集合中的元素(iterator() 方法是顺序遍历);

stream() & parallelStream(): JDK 1.8 引入的流(Stream)式数据处理,分别表示串行流和并行流,该部分以后单独分析。

List

List 是最常用的容器之一。之前提到过,分析源码时,优先分析接口的源码,因此这里先从 List 接口分析。List 方法列表如下:

// 将一个集合的所有元素添加到当前集合的指定位置;
boolean addAll(int index, Collection<? extends E> c);

// 用指定的运算结果替代集合中的所有元素
default void replaceAll(UnaryOperator<E> operator);

// 用指定的 Comporator 对集合元素进行排序
default void sort(Comparator<? super E> c);

// 获取指定位置的元素
E get(int index);

// 将某个位置的元素替换为指定元素
E set(int index, E element);

// 将指定元素添加到集合的指定位置
void add(int index, E element);

// 移除指定位置的元素
E remove(int index);

// 某个元素在集合中(第一次出现)的位置
int indexOf(Object o);

// 某个元素在集合中最后一次出现的位置
int lastIndexOf(Object o);

// 返回元素的列表迭代器
// 相当于 list.listIterator(0)
ListIterator<E> listIterator();

// 返回元素的 listIterator(指定起始位置)
ListIterator<E> listIterator(int index);

// 获取集合的子集
List<E> subList(int fromIndex, int toIndex);

Iterator

Iterator 接口是用于遍历集合元素的迭代器,它替代JCF中的 Enumeration 接口。方法概述如下:

// 是否有更多元素
boolean hasNext();

// 返回迭代的下一个元素
E next();

// 从底层集合中删除此迭代器返回的最后一个元素(可选操作)
// 每次调用 next() 时只能调用一次此该方法
default void remove();

// 对剩余的每个元素执行给定的操作
default void forEachRemaining(Consumer<? super E> action);

ListIterator

ListIterator,列表的迭代器,继承自 Iterator,可以从列表的两端进行遍历(Iterator 只能从前到后)。它在 Iterator 基础上增加方法如下:

// 是否有前一个元素(可理解为从后往前遍历)
boolean hasPrevious();

// 获取前一个元素
E previous();

// 返回对 next() 的后续调用将返回的元素的索引
// 如果列表迭代器位于列表的末尾,则返回列表大小
int nextIndex();

// 返回对 previous() 的后续调用将返回的元素的索引
// 如果列表迭代器位于列表的开头,则返回 -1
int previousIndex();

// 用指定的元素替换 next() 或 previous() 返回的最后一个元素
void set(E e);

// 插入指定元素到列表中
void add(E e);

二者的区别与联系:

ListIterator 继承自 Iterator.

都有 remove() 方法,都可以删除对象。

都有 next() 和 hasNext() 方法,都可以实现向后遍历;而 ListIterator 有 previous() 和 hasPrevious() 方法,可以向前遍历。

ListIterator 有 add() 和 set() 方法,可以向 List 添加和修改元素;而 Iterator 不能。

Queue 和 Deque 都是接口。其中 Queue 接口定义的是一个队列,它包含队列的基本操作:入队(enqueue)和出队(dequeue)。Deque 接口继承自 Queue 接口,表示双端队列(Double-ended queue),同时具备「队列」和「栈」的性质

Queue

入队:add() 和 offer()

二者区别在于:当队列空间已满无法入队时,add() 方法会抛出异常;而 offer() 会返回 false。

出队:remove() 和 poll()

二者区别在于:当队列为空时,remove() 方法会抛出异常,而 poll() 会返回 null。

遍历:element() 和 peek()

element() 和 peek() 都表示检索但不移除队列头部元素,可用于从头开始遍历队列。

二者区别在于:当队列为空时,element() 方法会抛出异常,而 peek() 会返回 null。

Deque

Deque 接口继承自 Queue 接口,可以将 Deque 理解为「双端队列 」和「栈(Stack)」的组合。一般的队列是从尾部插入元素、头部移除元素;而双端队列则可以分别从两端插入元素、两端移除元素。

Deque 还有几个独有的方法:

removeFirstOccurrence():从该双端队列中移除第一次出现的指定元素;

removeLastOccurrence():从该双端队列中移除最后一次出现的指定元素;

descendingIterator():以相反顺序返回此双端队列中元素的迭代器,可以认为是 iterator() 反过来。


Queue 和 Deque 都可用于表示队列;

Queue 表示基本的队列,包含队列的「入队」和「出队」操作;

Deque 继承自 Queue,除了基本的队列操作,Deque 是一个「双端队列」,可以认为它有两个头、两个尾;而且,Deque 还可以作为一个栈。

举报

相关推荐

0 条评论