[Java容器] Collection及其子接口List、Set、Queue源码解析

[Java容器] Collection及其子接口List、Set、Queue源码解析_第1张图片

目录

    • 一、Collection
    • 二、AbstractCollection
    • 三、List
    • 四、Set
    • 五、Queue
      • 5.1 Deque


一、Collection

单列集合的父类,在jdk1.8时新增了方法:

  • removeIf(Predicate filter),
  • stream(),
  • parallelStream(),
  • 继承于Iterable的forEach(Consumer action)的方法。
public interface Collection<E> extends Iterable<E> {
   
    // Query Operations
    int size();
    boolean isEmpty();
    boolean contains(Object o);
    Iterator<E> iterator();
    Object[] toArray();
    <T> T[] toArray(T[] a);

    // Modification Operations
    boolean add(E e);
    boolean remove(Object o);

    // Bulk Operations
    boolean containsAll(Collection<?> c);
    boolean addAll(Collection<? extends E> 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();

    // Comparison and hashing
    boolean equals(Object o);
    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);
    }
}

测试:

// removeIf:过滤集合,有过滤返回true,无变化返回false。
private static void testRemoveIf() {
    List<String> strings = new ArrayList<>();
    strings.add("a");
    strings.add("");
    strings.add("b");
    System.out.println(Arrays.toString(strings.toArray()));		// [a, , b]
    // 等价于 strings = strings.stream().filter(str -> !str.isEmpty()).collect(Collectors.toList());
    // 起到过滤作用
    strings.removeIf(String::isEmpty);	// true
    System.out.println(Arrays.toString(strings.toArray()));		// [a, b]
}

// containAll:取交集后赋给调用者,有变化返回true,无变化返回false。
private static void testRetainAll() {
    List<String> list1 = new ArrayList<>();
    list1.add("a");
    list1.add("b");
    list1.add("c");
    list1.add("d");
    
    List<String> list2 = new ArrayList<>();
    list2.add("a");
    list2.add("b");
    list2.add("c");
    list2.add("d");
    
    List<String> list3 = new ArrayList<>();
    list3.add("a");
    list3.add("b");
    list3.add("c");
    list3.add("e");
    
    // list1与list2做交集,结果集与list2做比较,如果相同返回true,否则返回false
    System.out.println("containAll:" + list1.containsAll(list2));	// containAll:true
    // retain是保留的意思,list1与list2做交集,结果集赋值给list1,如果list1被改变返回true,否则返回false
    System.out.println("retainAll:" + list1.retainAll(list2));	// retainAll:false
    System.out.println("retainAll:" + list1.retainAll(list3));	// retainAll:true
    System.out.println("list1:" + list1);	// list1:[a, b, c]
    System.out.println("list2:" + list2);	// list2:[a, b, c, d]
    System.out.println("list3:" + list3);	// list2:[a, b, c, e]
}

// 是一个并行执行的流,提高你的多线程任务的速度。
// 展示顺序不一定会是1、2、3、4、5、6、7、8、9,而可能是任意的顺序
private static void testParallelStream() {
    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
    numbers.parallelStream().forEach(out::println);
}

二、AbstractCollection

AbstractCollection 是Java集合框架中Collection接口的一个直接实现类,Collection下的大多数子类都继承AbstractCollection,比如 List 的实现类, Set的实现类。
AbstractCollection抽象类中已经实现了Collection中大部分接口,但是需要子类重写其抽象方法:

  • public abstract Iterator iterator();
  • public abstract int size();
public abstract class AbstractCollection<E> implements Collection<E> {

    protected AbstractCollection() {
    }

    // Query Operations
    
	// 需要子类自行重写
    public abstract Iterator<E> iterator();
    public abstract int size();

    public boolean isEmpty() {
        return size() == 0;
    }

	// 这里对null作了特别的处理
    public boolean contains(Object o) {
        Iterator<E> it = iterator();
        if (o==null) {
            while (it.hasNext())
                if (it.next()==null)
                    return true;
        } else {
            while (it.hasNext())
                if (o.equals(it.next()))
                    return true;
        }
        return false;
    }

    public Object[] toArray() {
        // Estimate size of array; be prepared to see more or fewer elements
        Object[] r = new Object[size()];
        Iterator<E> it = iterator();
        for (int i = 0; i < r.length; i++) {
            if (! it.hasNext()) // fewer elements than expected
                return Arrays.copyOf(r, i);
            r[i] = it.next();
        }
        return it.hasNext() ? finishToArray(r, it) : r;
    }

    @SuppressWarnings("unchecked")
    public <T> T[] toArray(T[] a) {
        // Estimate size of array; be prepared to see more or fewer elements
        int size = size();
        T[] r = a.length >= size ? a :
                  (T[])java.lang.reflect.Array
                  .newInstance(a.getClass().getComponentType(), size);
        Iterator<E> it = iterator();

        for (int i = 0; i < r.length; i++) {
            if (! it.hasNext()) { // fewer elements than expected
                if (a == r) {
                    r[i] = null; // null-terminate
                } else if (a.length < i) {
                    return Arrays.copyOf(r, i);
                } else {
                    System.arraycopy(r, 0, a, 0, i);
                    if (a.length > i) {
                        a[i] = null;
                    }
                }
                return a;
            }
            r[i] = (T)it.next();
        }
        // more elements than expected
        return it.hasNext() ? finishToArray(r, it) : r;
    }

    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    @SuppressWarnings("unchecked")
    private static <T> T[] finishToArray(T[] r, Iterator<?> it) {
        int i = r.length;
        while (it.hasNext()) {
            int cap = r.length;
            if (i == cap) {
                int newCap = cap + (cap >> 1) + 1;
                // overflow-conscious code
                if (newCap - MAX_ARRAY_SIZE > 0)
                    newCap = hugeCapacity(cap + 1);
                r = Arrays.copyOf(r, newCap);
            }
            r[i++] = (T)it.next();
        }
        // trim if overallocated
        return (i == r.length) ? r : Arrays.copyOf(r, i);
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError
                ("Required array size too large");
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }


    // Modification Operations

	// AbstractCollection 中默认不支持添加单个元素,如果直接调用 add(E) 方法,会报错
    public boolean add(E e) {
        throw new UnsupportedOperationException();
    }

    public boolean remove(Object o) {
        Iterator<E> it = iterator();
        if (o==null) {
            while (it.hasNext()) {
                if (it.next()==null) {
                    it.remove();
                    return true;
                }
            }
        } else {
            while (it.hasNext()) {
                if (o.equals(it.next())) {
                    it.remove();
                    return true;
                }
            }
        }
        return false;
    }


    // Bulk Operations

    public boolean containsAll(Collection<?> c) {
        for (Object e : c)
            if (!contains(e))
                return false;
        return true;
    }

    public boolean addAll(Collection<? extends E> c) {
        boolean modified = false;
        for (E e : c)
            if (add(e))
                modified = true;
        return modified;
    }

    public boolean removeAll(Collection<?> c) {
        Objects.requireNonNull(c);
        boolean modified = false;
        Iterator<?> it = iterator();
        while (it.hasNext()) {
            if (c.contains(it.next())) {
                it.remove();
                modified = true;
            }
        }
        return modified;
    }

    public boolean retainAll(Collection<?> c) {
        Objects.requireNonNull(c);
        boolean modified = false;
        Iterator<E> it = iterator();
        while (it.hasNext()) {
            if (!c.contains(it.next())) {
                it.remove();
                modified = true;
            }
        }
        return modified;
    }

    public void clear() {
        Iterator<E> it = iterator();
        while (it.hasNext()) {
            it.next();
            it.remove();
        }
    }

    //  String conversion
    public String toString() {
        Iterator<E> it = iterator();
        if (! it.hasNext())
            return "[]";

        StringBuilder sb = new StringBuilder();
        sb.append('[');
        for (;;) {
            E e = it.next();
            sb.append(e == this ? "(this Collection)" : e);
            if (! it.hasNext())
                return sb.append(']').toString();
            sb.append(',').append(' ');
        }
    }

}

三、List

List的特点:有序、可重复、元素为可空。
List的实现类:ArrayList、LinkedList、Vector。(子抽象类AbstractList)
ArrayList:底层由数组实现,允许元素随机访问,但是向 ArrayList 列表中间插入删除元素需要移位复制速度略慢。
LinkList:底层由双向链表实现,适合频繁向列表中插入删除元素,随机访问需要遍历所以速度略慢,适合当做堆栈、队列、双向队列使用。
Vector:实现原理和ArrayList几乎是相同的,线程安全。

public interface List<E> extends Collection<E> {
    // Query Operations
    int size();
    boolean isEmpty();
    boolean contains(Object o);
    Iterator<E> iterator();
    Object[] toArray();
    <T> T[] toArray(T[] a);

    // Modification Operations
    boolean add(E e);
    boolean remove(Object o);

    // Bulk Modification Operations
    boolean containsAll(Collection<?> c);
    boolean addAll(Collection<? extends E> c);
    //指定索引位置插入(在ArrayList和LinkedList中具体实现完全不同)
    boolean addAll(int index, Collection<? extends E> c);
    boolean removeAll(Collection<?> c);
    boolean retainAll(Collection<?> 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()));
        }
    }
	
	// 具体使用将案例
    @SuppressWarnings({"unchecked", "rawtypes"})
    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);
        }
    }
    
    void clear();

    // Comparison and hashing
    boolean equals(Object o);
    int hashCode();

    // Positional Access Operations
    E get(int index);
    E set(int index, E element);
    void add(int index, E element);
    E remove(int index);

    // Search Operations
    int indexOf(Object o);
    int lastIndexOf(Object o);

    // List Iterators
    ListIterator<E> listIterator();
    ListIterator<E> listIterator(int index);

    // View
    List<E> subList(int fromIndex, int toIndex);

    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, Spliterator.ORDERED);
    }
}
  • sort(Comparator c);
// 排序
private static void testSort() {
    ArrayList<Integer> arrayList = new ArrayList<>();
    arrayList.add(5);
    arrayList.add(4);
    arrayList.add(3);
    arrayList.add(2);
    arrayList.add(1);
    // 等价于:arrayList.sort(Integer::compareTo);
    arrayList.sort((o1, o2) -> o1.compareTo(o2));
    out.println(Arrays.toString(arrayList.toArray())); // [1, 2, 3, 4, 5]
}
  • ListIterator listIterator();

  • ListIterator listIterator(int index);
    详见:
    《迭代器(Iterable+Iterator+ListIterator+Enumeration)详解》

  • List subList(int fromIndex, int toIndex);
    此方法并没有创建一个新的 List,然后把旧List的指定范围子元素拷贝进新List中去。
    而是subList返回的是List原来的引用,只不过把开始位置 offset 和 size 改了。

AbstractList中的部分源码:

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
    public List<E> subList(int fromIndex, int toIndex) {
        return (this instanceof RandomAccess ?
                new RandomAccessSubList<>(this, fromIndex, toIndex) :
                new SubList<>(this, fromIndex, toIndex));
    }
}

class SubList<E> extends AbstractList<E> {
    private final AbstractList<E> l;
    private final int offset;
    private int size;

    SubList(AbstractList<E> list, int fromIndex, int toIndex) {
        if (fromIndex < 0)
            throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
        if (toIndex > list.size())
            throw new IndexOutOfBoundsException("toIndex = " + toIndex);
        if (fromIndex > toIndex)
            throw new IllegalArgumentException("fromIndex(" + fromIndex +
                                               ") > toIndex(" + toIndex + ")");
        l = list;
        offset = fromIndex;
        size = toIndex - fromIndex;
        this.modCount = l.modCount;
    }
}

测试:

private static void testSubList() {
    ArrayList<String> arrayList = new ArrayList<>();
    arrayList.add("a");
    arrayList.add("b");
    arrayList.add("c");
    arrayList.add("d");
    List<String> subList = arrayList.subList(0, 2);		// 包头不包尾

    out.println(Arrays.toString(subList.toArray()));	// [a, b]
    out.println(Arrays.toString(arrayList.toArray()));	// [a, b, c, d]
    
    // 对截取后的集合操作
    subList.remove(0);

    out.println(Arrays.toString(subList.toArray()));	// [b]
    out.println(Arrays.toString(arrayList.toArray()));	// [b, c, d]
}

结论:由于subList持有List同一个引用,所以对subList进行的操作也会影响到原有的List。


四、Set

Set的特点:无序、不可重复、元素为可空。
Set的实现类:HashSet、LinkHashSet(有序)、TreeSet。(子抽象类AbstractSet)
HashSet:是为快速查找元素而设计,存入 HashSet 的元素必须定义 hashCode 方法,其实质可以理解为是 HashMap 的包装类,所以 HashSet 的值还具备可 null 性;
LinkedHashSet:具备 HashSet 的查找速度且通过链表保证了元素的插入顺序(实质为 HashSet 的子类),迭代时是有序的,同理存入 LinkHashSet 的元素必须定义 hashCode 方法;
TreeSet:实质是 TreeMap 的包装类,所以 TreeSet 的值不备可 null 性,其保证了元素的有序性,底层为红黑树结构,存入TreeSet 的元素必须实现 Comparable 接口;不过特别注意 EnumSet 的实现和 EnumMap 没有一点关系。

Set的所有方法都是继承于Collection,所以源码没啥好看的。

public interface Set<E> extends Collection<E> {
    // Query Operations
    int size();
    boolean isEmpty();
    boolean contains(Object o);
    Iterator<E> iterator();
    Object[] toArray();
    <T> T[] toArray(T[] a);

    // Modification Operations
    boolean add(E e);
    boolean remove(Object o);

    // Bulk Operations
    boolean containsAll(Collection<?> c);
    boolean addAll(Collection<? extends E> c);
    boolean retainAll(Collection<?> c);
    boolean removeAll(Collection<?> c);
    void clear();

    // Comparison and hashing
    boolean equals(Object o);
    int hashCode();
    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, Spliterator.DISTINCT);
    }
}

五、Queue

Queue的特点:队列。
Queue 用来存放等待处理元素的集合,这种场景一般用于缓冲、并发访问。
支持 FIFO(first in first out)。

Queue的实现类:LinkedList、PriorityQueue。子接口:Deque
LinkedList:保证了按照元素的插入顺序进行操作;
PriorityQueue:按照优先级进行插入抽取操作,元素可以通过实现 Comparable 接口来保证优先顺序。
Deque:表示更为通用的双端队列,有明确的在头或尾进行查看、添加和删除的方法。

public interface Queue<E> extends Collection<E> {

	// 尾部添加,在添加失败(比如队列已满)时会报一些运行时错误。
    boolean add(E e);

	// 尾部添加,在添加失败时也不会奔溃,只会返回 false。
    boolean offer(E e);

	// 删除并返回头部,当队列为空时会报NoSuchElementException。
    E remove();
	
	// 删除并返回头部,当队列为空时不会奔溃,只会返回 null。
    E poll();

	// 获取但不删除,当队列为空时抛出异常。
    E element();

	// 获取但不删除,当队列为空时返回null。
    E peek();
}

测试:

private static void testQueue() {
    Queue<String> linkedList = new LinkedList<>();
    // out.println(linkedList.poll());  // null
    // linkedList.remove();             // java.util.NoSuchElementException
    // out.println(linkedList.peek());  // null
    // linkedList.element();            // java.util.NoSuchElementException
    linkedList.add("a");
    linkedList.add("b");
    linkedList.offer("c");
    linkedList.offer("d");
    // out.println(linkedList.remove());   // a

}

5.1 Deque

具体实现在LinkedList中查看。《List实现之LinkedList源码解析》
[Java容器] Collection及其子接口List、Set、Queue源码解析_第2张图片

你可能感兴趣的:(Java,Java集合)