2 集合

2.1 List,Collection,Iterable接口_iterator


       Java集合整体继承关系如上图所示,该结构图没有将map分支展示出来,对于map将在后续进行描述,java中collection是一个经常用到的工具,熟悉其使用和方法都是十分必要的,接下来笔者将会把java中的集合抽丝剥茧的呈现给诸位。


2.1 List接口

2.1.1 List接口的继承关系

       List接口的继承关系如下,最上层是Iterable接口,Collection接口继承自顶层接口Iterable,List又继承了Collection。

2.1 List,Collection,Iterable接口_iterator_02



2.1.2 Iterable接口

       源码如下:

package java.lang;

import java.util.Iterator;
import java.util.Objects;
import java.util.Spliterator;
import java.util.Spliterators;
//支持lambda函数接口
import java.util.function.Consumer;
public interface Iterable<T> {
    Iterator<T> iterator();
    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
    default Spliterator<T> spliterator() {
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
}

       该接口表示是否可以迭代的,并且支持forEach遍历,Java8常常用forEach配合和lambda表达式,该表达式是实现Consumer接口中accept方法的使用。

2.1.3 Collection接口

Collection接口源码:

package java.util;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public interface Collection<E> extends Iterable<E> {
    int size();
    boolean isEmpty();
    boolean contains(Object o);
    Iterator<E> iterator();
    Object[] toArray();
    boolean add(E e);
    boolean remove(Object o);
    boolean containsAll(Collection<?> c);
    boolean removeAll(Collection<?> c);
    default boolean removeIf(Predicate<? super E> filter) {
        Objects.requireNonNull(filter);
        boolean removed = false;
        final Iterator<E> each = iterator();
        while (each.hasNext()) {
            if (filter.test(each.next())) {
                each.remove();
                removed = true;
            }
        }
        return removed;
    }
    boolean retainAll(Collection<?> c);
    void clear();
    int hashCode();
    @Override
    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的主要接口方法有:

接口

作用

int size();

集合大小

boolean isEmpty();

集合是否为空

boolean contains(Object o);

是否包含某元素

Iterator iterator()

迭代

Object[] toArray()

转数组

boolean add(E e);

添加元素

boolean remove(Object o)

移除某元素

boolean containsAll(Collection<?> c)

是否包含另一个集合

boolean removeAll(Collection<?> c)

移除集合所有


2.1.4 List接口

       再来看看List接口,笔者将List中包含Collection的接口移除掉了:

package java.util;

import java.util.function.UnaryOperator;
public interface List<E> extends Collection<E> {
    <T> T[] toArray(T[] a);
    boolean addAll(Collection<? extends E> c);
    boolean addAll(int index, Collection<? extends E> c);
    default void replaceAll(UnaryOperator<E> operator) {
        Objects.requireNonNull(operator);
        final ListIterator<E> li = this.listIterator();
        while (li.hasNext()) {
            li.set(operator.apply(li.next()));
        }
    }
    default void sort(Comparator<? super E> c) {
        Object[] a = this.toArray();
        Arrays.sort(a, (Comparator) c);
        ListIterator<E> i = this.listIterator();
        for (Object e : a) {
            i.next();
            i.set((E) e);
        }
    }
    boolean equals(Object o);
    E get(int index);
    E set(int index, E element);
    void add(int index, E element);
    int indexOf(Object o);
    int lastIndexOf(Object o);
    ListIterator<E> listIterator();
    List<E> subList(int fromIndex, int toIndex);
    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, Spliterator.ORDERED);
    }
}

       可以看到List其实比Collection多了添加方法add和addAll查找方法get,indexOf,set等方法,并且支持index下标操作

2.1.5 Collection与List的区别

       a. 从上边可以看出Collection和List最大的区别就是Collection是无序的,不支持索引操作,而List是有序的。Collection没有顺序的概念。
       b. List中Iterator为ListIterator。
       c. 由a推导List可以进行排序,所以List接口支持使用sort方法。
       d. 二者的Spliterator操作方式不一样。

2.1.6 为什么子类接口里重复申明父类接口呢?

       官方解释: **在子接口中重复声明父接口是为了方便看文档。**比如在java doc文档里,在List接口里也能看到Collecion声明的相关接口。