这篇是相当简单的梳理了下 Java 集合类之间的关系, 和各个类是干嘛的, 所以如果您知道这些话, 那么这篇看到这您就可以关掉了
上面是 Java 集合的大致继承实现关系, 我们只拿出了一部分的实现类, 但是本文并不介绍具体的实现类, 而只是介绍一下 Java 的集合的架构.
Iterable
其接口定义
public interface Iterator<E> { {...}
下面是其中的方法
- // 判断是否有下一个元素
- boolean hasNext();
- // 下一个元素
- E next();
- // 默认
- default void remove() {
- ...
- }
- default void forEachRemaining(Consumer<? super E> action) {
- ...
- }
在 Java8 更新后, 那么接口中就增加了默认实现, 所以在这个接口中主要担任实现整体集合类的遍历和删除等工作
Iterator 遍历 Collection 时, 是 fail-fast 机制的, 即当某一个线程 A 通过 iterator 去遍历某集合的过程中, 若该集合的内容被其他线程所改变了. 那么线程 A 访问集合时, 就会抛出 ConcurrentModificationException 异常, 产生 fail-fast 事件
Collection
接口定义
public interface Collection<E> extends Iterable<E> {...}
下面是其中的方法
- int size();
- boolean isEmpty();
- boolean isEmpty();
- Iterator<E> iterator();
- Object[] toArray();
- <T> T[] toArray(T[] a);
- boolean add(E e);
- boolean remove(Object o);
- boolean containsAll(Collection<?> c);
- boolean addAll(Collection<? extends E> c);
- boolean removeAll(Collection<?> c);
- default boolean removeIf(Predicate<? super E> filter) {
- ...
- }
- boolean retainAll(Collection<?> c);
- void clear();
- boolean equals(Object o);
- int hashCode();
- default Spliterator<E> spliterator() {
- return Spliterators.spliterator(this, 0);
- }
- default Stream<E> stream() {
- return StreamSupport.stream(spliterator(), false);
- }
- default Stream<E> parallelStream() {
- return StreamSupport.stream(spliterator(), true);
- }
我们从上面的图中可以看到, Collection 是 List 和 Set 的一个高度抽象, 所以此类中定义的方法, 都是 List 和 Set 一些集合共通的方法, 并且其中也包含了 Java8 的默认方法, 为 Java8 新提供的 Stream 和 Lambda 提供默认实现
List
定义如下
public interface List<E> extends Collection<E> {...}
下面是其中的方法
- boolean addAll(int index, Collection<? extends E> c);
- boolean removeAll(Collection<?> c);
- int indexOf(Object o);
- ListIterator<E> listIterator();
- List<E> subList(int fromIndex, int toIndex);
- E get(int index);
- E set(int index, E element);
- void add(int index, E element);
- ...
List 继承 Collection, 所以除了将 Collection 的方法继承过来后, 又定义实现了自己的一些特有方法, 比如 subList,get,add 等等, List 是有序的队列, List 中的每一个元素都有一个索引, 第一个元素的索引值是 0, 往后的元素的索引值依次 + 1,List 中允许有重复的元素.
AbstractCollection
定义
public abstract class AbstractCollection<E> implements Collection<E> {}
包含的方法
- public abstract Iterator<E> iterator();
- public abstract int size();
- public boolean contains(Object o) {
- ...
- }
- public Object[] toArray() {
- ...
- }
- public Object[] toArray() {
- ...
- }
- private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
- ....
我们可以看到这个抽象类是在直接实现了 Collection 接口, 并在自己的类中部分实现了 Collection 中的方法, 其目的就是为其子类提供一些默认实现, 而子类一些行为, 并没有给出默认实现, 这就利用了继承的便利来复用代码
Set
定义
public interface Set<E> extends Collection<E> {...}
包含的方法
- int size();
- boolean isEmpty();
- boolean add(E e);
- boolean containsAll(Collection<?> c);
- boolean addAll(Collection<? extends E> c);
- boolean removeAll(Collection<?> c);
- Object[] toArray();
- ...
Set 实现了 Collection 接口, 并且我发现 Set 的 API 基本跟 Collection 一致, 并没有一一对比, 所以这个 Set 接口也没有什么特殊要说的
AbstractList
定义
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {...}
包含的方法
- abstract public E get(int index);
- public void add(int index, E element) {
- throw new UnsupportedOperationException();
- }
- public void clear() {
- removeRange(0, size());
- }
- public ListIterator<E> listIterator(final int index) {
- rangeCheckForAdd(index);
- return new ListItr(index);
- }
- ...
这个类是继承自 AbstractCollection, 那么 AbstractCollection 继承 Collection, 所以这也就形成了一层层的包装, 使得之后的实现类更容易实现自己的逻辑, 达到代码复用的目的
并且其中包含了一些内部类, 其定义如下
- private class Itr implements Iterator<E> {
- ...
- }
- private class ListItr extends Itr implements ListIterator<E> {
- ...
- }
还有两个类的定义是在其同源文件中定义的类
- class SubList<E> extends AbstractList<E> {
- ...
- }
- class RandomAccessSubList<E> extends SubList<E> implements RandomAccess {
- ...
- }
- RandomAccess&Serialiable&Cloneable
这三个的定义分别是
- public interface RandomAccess {
- }
- public interface Cloneable {
- }
- public interface Serializable {
- }
三个接口并没有一个方法的定义或者实现, 其目的在于标识这个接口可以干什么, 即可随机访问又可以序列化可克隆
剩余
除了详细实现的实现类, 剩余的 AbstractList,AbstractSet,AbstractMap 都是对其父类的简单实现, 以方便其子类实现逻辑, 那么单独出来的 Map 接口我们需要注意的是, 虽然同属于 Java 集合, 但是他并不是继承自 Collection, 这是要注意的, 其每个接口的具体实现类, 之后会进行说明
总结
其实今天的很简单, 并且自己感觉这篇比较水, 但是这也为自己梳理了下 Java 集合的类关系图, 所以这也为之后深入 Java 集合提供了一个简单的基础, 那么我们还可以吸收到能为自己所用的一点是, Java 集合的抽象过程, 即最通用的抽象出来接口后在依次丰富其接口, 这样可扩展性就会很好了
来源: https://yq.aliyun.com/articles/688734