从源码上看ArrayList的继承关系如下图所示:

Iterable接口
Iterable接口是集合框架的顶层接口,表明"可迭代"/"可遍历查询"的能力。
Iterable有一个iterator方法,需要实现类重写该方法。
java
Iterator<T> iterator(); // 返回一个迭代器对象,迭代器对象可对Iterable对象进行迭代遍历
Iterable有两个默认方法(已实现的方法):
java
//对 Iterable 的每个元素执行给定操作,直到处理完所有元素或操作引发异常
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
//创建一个 Spliterator 用于遍历和分区此 Iterable 描述的元素
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
Collection集合接口(以及它的所有子接口如 List, Set)继承Iterable接口,因此所有的集合对象都可以用迭代器,可以使用forEach方法来遍历元素执行函数。
java
public class Demo8 {
public static void main(String[] args) {
// 创建一个Collection接口对象(Collection接口继承Iterable接口)
Collection<String> list = new ArrayList<>();
list.add("hello");
list.add("world");
list.add("java");
// 创建一个迭代器对象
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String s = it.next();
System.out.println(s);
}
// 用forEach方法遍历集合
list.forEach(s -> System.out.println(s));
}
}
一般来说,我们不需要自定义实现Iterable接口的类,因为Java内置的集合框架已经够用了。但是如果你想让一个自定义的类实现增强for循环遍历,或者能够迭代遍历,就必须实现Iterable 接口。
Collection接口
Collection是集合类的根接口之一,Collection接口继承Iterable接口。
Collection的常用方法有:
- 基本操作方法
java
// 返回集合中元素的数量
int size();
// 判断集合是否为空
boolean isEmpty();
// 判断是否包含指定元素
boolean contains(Object o);
// 向集合中添加元素(可选操作)
boolean add(E e);
// 从集合中移除元素(可选操作)
boolean remove(Object o);
- 批量操作方法
java
// 判断是否包含指定集合的所有元素
boolean containsAll(Collection<?> c);
// 添加指定集合的所有元素(可选操作)
boolean addAll(Collection<? extends E> c);
// 移除与指定集合相同的所有元素(可选操作)
boolean removeAll(Collection<?> c);
// 仅保留与指定集合相同的元素(可选操作)
boolean retainAll(Collection<?> c);
// 清空集合(可选操作)
void clear();
- 数组转化方法
java
// 返回包含所有元素的数组
Object[] toArray();
// 返回指定类型的数组
<T> T[] toArray(T[] a);
- Java 8+ 新增的默认方法
java
// 返回顺序流
default Stream<E> stream()
// 返回并行流
default Stream<E> parallelStream()
// 根据条件删除元素
default boolean removeIf(Predicate<? super E> filter)
- 继承自Iterable的方法
java
// 返回集合的迭代器
Iterator<E> iterator();
// 分割迭代器(用于并行处理)
default Spliterator<E> spliterator()
// 对 Iterable 的每个元素执行给定操作
void forEach(Consumer<? super T> action)
注意:"可选操作"是指某些方法在某些具体实现类中可能不被支持,具体实现类可以在重写方法时抛出异常。
常用方法演示如下:
java
public class Demo9 {
public static void main(String[] args) {
// 创建一个集合对象
Collection<String> list = new ArrayList<>();
list.add("hello");
list.add("world");
list.add("java");
// 1. 基本操作方法
// 返回集合中元素的数量
System.out.println(list.size()); // 3
// 判断集合是否为空
System.out.println(list.isEmpty()); // false
// 判断是否包含指定元素
System.out.println(list.contains("hello")); // true
// 向集合中添加元素(可选操作)
list.add("python");
System.out.println(list); // [hello, world, java, python]
// 删除集合中的元素(可选操作)
list.remove("java");
System.out.println(list); // [hello, world, python]
// 2. 批量操作方法
// 判断是否包含指定集合的所有元素
System.out.println(list.containsAll(list)); // true
// 添加指定集合的所有元素(可选操作)
Collection<String> list2 = new ArrayList<>();
list2.add("this");
list2.add("is");
list2.add("a");
list2.add("test");
list.addAll(list2);
System.out.println(list); // [hello, world, python, this, is, a, test]
// 移除与指定集合相同的所有元素(可选操作)
list.removeAll(list2);
System.out.println(list); // [hello, world, python]
// 仅保留与指定集合相同的元素(可选操作)
list.addAll(list2);
System.out.println(list); // [hello, world, python, this, is, a, test]
list.retainAll(list2);
System.out.println(list); // [this, is, a, test]
// 清空集合(可选操作)
list.clear();
System.out.println(list); // []
// 3. 数组转化方法
Collection<String> list3 = new ArrayList<>();
list3.add("ni");
list3.add("hao");
list3.add("ma");
// 返回包含所有元素的数组
Object[] arr = list3.toArray();
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
// 返回指定类型的数组
String[] arr2 = list3.toArray(new String[0]);
for (int i = 0; i < arr2.length; i++) {
System.out.println(arr2[i]);
}
}
}
AbstractCollection抽象类
AbstractCollection是一个实现Collection接口的抽象类,意味着它实现了一部分接口的方法,包括从Iterable间接继承的方法。
AbstractCollection实际上只有两个抽象方法没有实现,这两个方法都依赖具体实现类的数据结构。
java
public abstract Iterator<E> iterator(); // 继承自Iterable
public abstract int size(); // 继承自Collection
AbstractCollection已经实现的方法,都是基于这两个抽象方法,以及从Collection接口直接继承和Iterable间接继承的默认实现方法来实现的。比如isEmpty()方法,是基于size() 方法实现:
java
public boolean isEmpty() {
return size() == 0;
} // 基于size()方法实现
以下是一些已实现的方法:
- isEmpty() - 基于 size() 实现
- contains(Object o) - 基于迭代器遍历实现
- toArray() - 基于迭代器和数组复制实现
- toArray(T[] a) - 泛型版本,更复杂的数组处理
- add(E e) - 默认抛出 UnsupportedOperationException
- remove(Object o) - 基于迭代器遍历实现
- containsAll(Collection< ?> c) - 基于 contains() 实现
- addAll(Collection< ? extends E> c) - 基于迭代器和 add() 实现
- removeAll(Collection< ?> c) - 基于迭代器和 contains() 实现
- retainAll(Collection< ?> c) - 基于迭代器和 contains() 实现
- clear() - 基于迭代器的 remove() 方法实现
为什么要专门编写一个AbstractCollection抽象类?这是因为这个抽象类,可以把框架的大部分方法实现,而到最后的具体实现类,只需要编写剩余很少的方法。也就是核心目的是减少重复代码,让具体集合类只关注核心数据结构。这种思路很适合一个接口具有多个实现类的场景。
List接口
List接口继承Collection接口,也就间接继承了Iterable接口,即继承了以上接口的所有方法。
List即"列表",可以理解是一类特殊的"集合",是一类有序、可被索引的集合。相比与Collection,List 对 equals() 和 hashCode() 有更严格的契约:
- 必须考虑元素的顺序
- 两个列表相等必须:大小相同 + 对应位置元素相等
List新增了一些方法,几乎都是跟索引有关,比如:
java
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); // 返回元素最后一次出现的索引
boolean addAll(int index, Collection<? extends E> c); // 在指定位置插入集合中的所有元素
List<E> subList(int fromIndex, int toIndex); // 返回子列表视图
List接口,本身是继承了Iteratable接口的迭代Iterator相关方法。但List接口新定义了有关列表迭代器ListIterator相关方法:
java
ListIterator<E> listIterator(); // 返回列表迭代器
ListIterator<E> listIterator(int index); // 从指定位置返回列表迭代器
ListIterator 比普通 Iterator 多了以下功能:
- 可以向前遍历(hasPrevious(), previous())
- 可以获取当前索引(nextIndex(), previousIndex())
- 可以在遍历时添加元素(add(E e))
- 可以在遍历时修改元素(set(E e))
另外,List接口也提供了一些默认实现的方法。
java
// Java 8+ 引入的默认方法:
default void replaceAll(UnaryOperator<E> operator) // 替换所有元素
default void sort(Comparator<? super E> c) // 排序
default Spliterator<E> spliterator() // 创建分割迭代器
// Java 9+ 引入的静态工厂方法:
static <E> List<E> of(E... elements) // 创建不可修改列表
static <E> List<E> copyOf(Collection<E> coll) // 创建副本
AbstractList抽象类
AbstractList是一个抽象类,它继承了AbstractCollection抽象类,又实现了List接口。因此,它继承了Iterable接口、Collection接口、List接口的所有方法,又继承了AbstractCollection的抽象和实现方法。
AbstractList和AbstractCollection作用相似,尽可能的实现List接口框架性的默认实现方法,仅保留少部分抽象方法,让子实现类去实现。
AbstractList 只要求子类必须实现两个核心方法:
java
abstract E get(int index);
abstract int size();
其他方法都是基于继承的默认方法,以及这两个核心方法的实现。