Java基础知识之容器(一:容器整体框架探索)

java框架系列文章相关地址:

Java基础知识之容器(一:容器整体框架探索)
Java基础知识之容器(二:ArrayList详解)
Java基础知识之容器(三:LinkedList详解)
Java基础知识之容器(四:Vector详解)
Java基础知识之容器(五:HashSet详解)
Java基础知识之容器(六:TreeSet详解)
Java基础知识之容器(七:HashMap详解)
Java基础知识之容器(八:HashMap在jdk8数据结构的改进)

本篇博客主要介绍Java容器的框架,我们根据框架重上向下的顺序一个个探究其源码,来达到掌握容器的骨架。至于容器的细节放到下一篇来探讨。

一:基本概念

Java容器类库的用途是保存对象,根据数据结构不同将其划分为两个不同的概念

  • Collection,一个独立元素的序列,其中List按照元素的插入顺序保存元素,而set不能有重复元素,Queue按照先进先出(FIFO)的方式来管理数据
  • Map,一组键值对(key-value)对象的序列,可以使用key来查找value,其中key是不可以重复的,value可以重复。我们可以称其为字典或者关联数组。其中HashMap是无序的,TreeMap是有序的,WeakHashMap是弱类型的,Hashtable是线程安全的。

二:框架结构图

Collection的List、Set、Queue类图如下:
这里写图片描述

Map容器的类图如下:
这里写图片描述

三:源码探索

Iterable接口

import java.util.Iterator;

/**
 * 实现此接口的类的实例可以与增强型for循环一起使用。
 * @since 1.5
 */
public interface Iterable<T> {

    /**
     * 返回此对象中元素的迭代器
     */
    Iterator<T> iterator();
}
/**
 * 一系列对象的迭代器,如集合。
 */
public interface Iterator<E> {
    /**
     * 如果至少有一个元素返回true,否则返回false。
     */
    public boolean hasNext();

    /**
     * 返回下一个对象并推进迭代器。
     */
    public E next();

    /**
     * 从集合中删除{@code next}返回的最后一个对象。
     * 这种方法只能在每次调用{@code next}之前调用一次。
     */
    public void remove();
}
  • Iterator是迭代器类,而Iterable是为了只要实现该接口就可以使用foreach,进行迭代.
  • Iterable中封装了Iterator接口,只要实现了Iterable接口的类,就可以使用Iterator迭代器了。
  • 集合Collection、List、Set都是Iterable的实现类,所以他们及其他们的子类都可以使用foreach进行迭代。
  • Iterator中和核心的方法next(),hasnext(),remove(),都是依赖当前位置,如果这些集合直接实现Iterator,则必须包括当前迭代位置的指针。当集合在方法间进行传递的时候,由于当前位置不可知,所以next()之后的值,也不可知。而当实现Iterable则不然,每次调用都返回一个从头开始的迭代器,各个迭代器之间互不影响。

从上面我们可以看出,Iterable只是为了让集合能够使用迭代器而已

Collection接口

/**
 * 集合层次结构中的根接口。
 * 一个集合表示一组对象,称之为元素,有些集合允许重复元素,而其他集合不允许。
 * 一些是有序的,另一些是无序的。 
 * JDK不提供此接口的任何直接实现:它提供了更多特定子接口的实现,如Set和List
 * 
 * 所有通用的Collection实现类(通常通过其子接口间接实现Collection)应该提供两个“标准”构造函数:
 * void(无参数) 构造函数,它创建一个空集合,以及一个带有Collection类型的单个参数的构造函数,
 * 它创建一个与它的参数具有相同元素的新集合。实际上,后者的构造函数允许用户复制任何集合,生成所需实现类型的等效集合。
 * 没有办法强制执行这个约定(因为接口不能包含构造函数),但是Java平台库中的所有通用Collection实现都符合。
 *   
 * 如果这个集合不支持某个操作的话,调用这些方法可能(但不是必需)抛出 UnsupportedOperationException  
 **/
public interface Collection<E> extends Iterable<E> {

    /**
     * 尝试将对象添加到此集合的内容(可选)。
     *
     * 此方法成功完成后,可确保对象包含在集合中。
     *
     * 如果集合被修改,则返回true,如果没有更改,则返回false。
     *
     * Collection的一个实现可能缩小了接受对象的集合,但它必须在文档中指定。 如果要添加的对象不符合此限制,则抛出IllegalArgumentException。
     *
     * 如果集合尚未包含要添加的对象并添加对象失败,则此方法<i>必须</ i>抛出适当的未选中的异常。 在这种情况下,不允许返回false,因为在该方法完成后,它将违反元素将成为集合的一部分的后置条件。
     */
    public boolean add(E object);

    /**
     * 清空集合元素
     */
    public void clear();

    /**
     * 测试此集合是否包含指定的对象。 如果且仅当此Collection中的至少一个元素元素满足以下要求(object == null?elem == null:object.equals(elem))},则返回true。
     */
    public boolean contains(Object object);

    /**
     * 此集合是否包含指定集合中所有的元素
     */
    public boolean containsAll(Collection<?> collection);

    /**
     * 如果对象与此对象相同,则返回true,如果该对象与此对象不同,则返回false。
     */
    public boolean equals(Object object);

    /**
     * 返回接收器的整数哈希码。 相同的对象为此方法返回相同的值。
     */
    public int hashCode();

    /**
     * 如果此Collection不包含元素,则返回true
     */
    public boolean isEmpty();

    /**
     * 返回可用于访问此Collection所包含的对象的Iterator实例。 没有定义迭代器返回元素的顺序。 只有当Collection的实例具有定义的顺序时,才能按照该顺序返回元素。
     */
    public Iterator<E> iterator();

    /**
     * 从此集合中删除指定对象的一个实例
     */
    public boolean remove(Object object);

    /**
     * 删除指定集合(可选)中每个对象的{@code Collection}中的所有事件。 在此方法返回后,该集合中的所有元素都不能在此集合中找到。
     */
    public boolean removeAll(Collection<?> collection);

    /**
     * 从集合中删除在集合中未找到的所有对象(可选)。 在此方法返回后,此集合将只包含可以在传递给此方法的集合中找到的元素。(求交集)
     */
    public boolean retainAll(Collection<?> collection);

    /**
     *返回此集合包含多少对象的计数。
     */
    public int size();

    /**
     * 返回一个包含此集合中包含的所有元素的新数组。
     *
     * 如果实现已经排序了元素,它将以与迭代器返回的顺序相同的顺序返回元素数组。
     *
     * 返回的数组不反映集合的任何更改。 即使底层数据结构已经是一个数组,也创建一个新数组。
     */
    public Object[] toArray();

    /**
     * 返回包含此集合中包含的所有元素的数组。 如果指定的数组足够大以容纳元素,则使用指定的数组,否则将创建相同类型的数组。 如果使用指定的数组并且大于此集合,则Collection元素之后的数组元素将设置为null。
     */
    public <T> T[] toArray(T[] array);
}
  • Collection接口是Java语言中最基本的集合接口,在JDK中没有直接提供Collection接口的具体实现类,Collection的功能实现类主要是对它的三个更具体的子接口List、Set和Queue的具体实现类。但是在Collection接口中定义了一套通用操作的实现方法和命名规则。
  • List、Set、Queue接口都继承自Collection并定义了各自不同的方法。

List接口探索

/** 
 * List是维护其元素的排序的集合。 List中的每个元素都有一个索引。 因此,每个元素可以被其索引访问,第一个索引为零。 
 * 通常,与集合相比,List允许重复元素,其中元素必须是唯一的。
 * 有序集合(也称为<i>序列</ i>)。 该接口的用户可以精确控制每个元素插入到列表中的哪个位置。 
 * 用户可以通过整数索引(列表中的位置)访问元素,并搜索列表中的元素。
 * 
 * 列表允许重复元素,也允许null元素插入
 */  
public interface List<E> extends Collection<E> {  
    /**List作为Collection的子接口 
     * 提供了Collection接口定义的方法 
     * 这些方法在Collection源码学习中 
     * 已经分析过了,就不在说明了 
     * */  
    int size();  
    boolean isEmpty();  
    boolean contains(Object o);  
    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 addAll(int index, Collection<? extends E> c);  
    boolean removeAll(Collection<?> c);  
    boolean retainAll(Collection<?> c);  
    void clear();  
    boolean equals(Object o);  
    int hashCode();  
    /**同时List接口定义了一些自己的方法 
     * 来实现“有序”这一功能特点*/  
    /** 
     *返回列表中指定索引的元素 
     *return E 
     *throws IndexOutofBoundException(index<0||index>=size()) 
     * */  
    E get(int index);  
    /** 
     *设定某个列表索引的值  
     *throws: 
     *UnsupportedOperationException  
      ClassCastException  
      NullPointerException  
      IllegalArgumentException  
      IndexOutOfBoundsException  
     * */  
    E set(int index, E element);  
    /** 
     *在指定位置插入元素,当前元素和后续元素后移 
     *这是可选操作,类似于顺序表的插入操作 */  
    void add(int index, E element);  
    /** 
     * 删除指定位置的元素(可选操作)*/  
    E remove(int index);  
    /** 
     * 获得指定对象的最小索引位置, 
     * 没有则返回-1*/  
    int indexOf(Object o);  
    /**获得指定对象的最大索引位置 
     * 可以知道的是若集合中无给定元素的重复元素下 
     * 其和indexOf返回值是一样的*/  
    int lastIndexOf(Object o);  
    /**一种更加强大的迭代器,支持向前遍历,向后遍历 
     * 插入删除操作,此处不解释*/  
    ListIterator<E> listIterator();  
    ListIterator<E> listIterator(int index);  
    /** 
     * 返回索引fromIndex(包括)和toIndex(不包括) 
     * 之间的视图。*/  
    List<E> subList(int fromIndex, int toIndex);  
}  

List接口特点
* 内部元素是有序的
* 元素是可以重复的
* List接口有3个常用的实现类,分别是ArrayList、LinkedList、Vector。

Set 接口探索

/**
 * Set是不允许重复元素的数据结构。
 */
public interface Set<E> extends Collection<E> {
    /**Set作为Collection的子接口 
     * 提供了Collection接口定义的方法 
     * 这些方法在Collection源码学习中 
     * 已经分析过了,就不在说明了 
     * */  
    public boolean add(E object);
    public boolean addAll(Collection<? extends E> collection);
    public void clear();
    public boolean contains(Object object);
    public boolean containsAll(Collection<?> collection);
    public boolean equals(Object object);
    public int hashCode();
    public Iterator<E> iterator();
    public boolean remove(Object object);
    public boolean removeAll(Collection<?> collection);
    public boolean retainAll(Collection<?> collection);
    public Object[] toArray();
    public <T> T[] toArray(T[] array);
    public boolean isEmpty();
    public int size();
}

Set接口特点
* 内部元素是无序的
* 元素是不可以重复的
* Set接口有2个常用的实现类,HashSet、TreeSet。
* Set基于哈希算法实现

Queue 接口探索

public interface Queue<E> extends Collection<E> {
    /**
     * 队列插入元素
     *
     * @param e the element to add
     * @return <tt>true</tt> (as specified by {@link Collection#add})
     * @throws IllegalStateException if the element cannot be added at this
     *         time due to capacity restrictions
     * @throws ClassCastException if the class of the specified element
     *         prevents it from being added to this queue
     * @throws NullPointerException if the specified element is null and
     *         this queue does not permit null elements
     * @throws IllegalArgumentException if some property of this element
     *         prevents it from being added to this queue
     */
    boolean add(E e);

    /**
     * 队列插入元素
     * 插入失败,抛出异常
     * @param e the element to add
     * @return <tt>true</tt> if the element was added to this queue, else
     *         <tt>false</tt>
     * @throws ClassCastException if the class of the specified element
     *         prevents it from being added to this queue
     * @throws NullPointerException if the specified element is null and
     *         this queue does not permit null elements
     * @throws IllegalArgumentException if some property of this element
     *         prevents it from being added to this queue
     */
    boolean offer(E e);

    /**
     * 获取队顶元素,并删除该元素
     * 空的时候,抛出异常
     * @return the head of this queue
     * @throws NoSuchElementException if this queue is empty
     */
    E remove();

    /**
     * 获取队顶元素,并删除该元素
     * 空的时候,返回null
     * @return the head of this queue, or <tt>null</tt> if this queue is empty
     */
    E poll();

    /**
     * 查看队顶元素,但是不删除该元素、
     * 空的时候,抛出异常
     * @return the head of this queue
     * @throws NoSuchElementException if this queue is empty
     */
    E element();

    /**
     * 查看队顶元素,但是不删除该元素、
     * 空的时候,返回 null
     *
     * @return the head of this queue, or <tt>null</tt> if this queue is empty
     */
    E peek();
}

Queue接口特点

  • 先进先出的数据结构,即从容器的一端放入对象,从另一端取出,并且对象放入容器的顺序与取出的顺序是相同的。
  • 虽然Queue接口继承Collection接口,但是Queue接口中的方法都是独立的,在创建具有Queue功能的实现时,不需要使用Collection方法。

AbstractCollection抽象类探索

/**
 * 该类提供了Collection接口的骨架实现,以最小化实现此接口所需的工作量。
 *
 * 要实现一个不可修改的集合,程序员只需要扩展这个类并为iterator和size方法提供实现(由 iterator方法返回的迭代器必须实
 * 现 hasNext 和 next).
 *
 * 为了实现一个可修改的集合,程序员必须另外重写这个类的 add 方法(否则抛出一个 UnsupportedOperationException ),并
 * 且iterator方法返回的迭代器必须实 remove方法.
 *
 * 根据Collection 接口规范中的建议,程序员通常应该提供一个void(无参数)和 Collection 构造函数。
 *
 * 这个类中每个非抽象方法的文档都详细描述了它的实现。 如果正在实施的集合允许更有效的实现,则可以重写这些方法中的每一个。
 */
public abstract class AbstractCollection<E> implements Collection<E> {
    protected AbstractCollection() {
    }

    /**
     * 覆盖Collection中的方法,默认是不可变的集合,要创建可修改的集合,有必要重此方法
     */
    public boolean add(E object) {
        throw new UnsupportedOperationException();
    }

    /**
     * 覆盖并实现Collection中的addAll方法
     */
    public boolean addAll(Collection<? extends E> collection) {
        boolean result = false;
        Iterator<? extends E> it = collection.iterator();
        while (it.hasNext()) {
            if (add(it.next())) {
                result = true;
            }
        }
        return result;
    }

    /**
     * 覆盖并实现Collection中的clear方法
     */
    public void clear() {
        Iterator<E> it = iterator();
        while (it.hasNext()) {
            it.next();
            it.remove();
        }
    }
    /**
     * 覆盖并实现Collection中的contains方法
     */
    public boolean contains(Object object) {
        Iterator<E> it = iterator();
        if (object != null) {
            while (it.hasNext()) {
                if (object.equals(it.next())) {
                    return true;
                }
            }
        } else {
            while (it.hasNext()) {
                if (it.next() == null) {
                    return true;
                }
            }
        }
        return false;
    }
    /**
     * 覆盖并实现Collection中的containsAll方法
     */
    public boolean containsAll(Collection<?> collection) {
        Iterator<?> it = collection.iterator();
        while (it.hasNext()) {
            if (!contains(it.next())) {
                return false;
            }
        }
        return true;
    }
    /**
     * 覆盖并实现Collection中的isEmpty方法
     */
    public boolean isEmpty() {
        return size() == 0;
    }

    /**
     * 在这个类中,这个方法被声明为抽象的,必须由具体的Collection实现来实现。
     */
    public abstract Iterator<E> iterator();

    /**
     * 覆盖并实现Collection中的remove方法
     */
    public boolean remove(Object object) {
        Iterator<?> it = iterator();
        if (object != null) {
            while (it.hasNext()) {
                if (object.equals(it.next())) {
                    it.remove();
                    return true;
                }
            }
        } else {
            while (it.hasNext()) {
                if (it.next() == null) {
                    it.remove();
                    return true;
                }
            }
        }
        return false;
    }
    /**
     * 覆盖并实现Collection中的removeAll方法
     */
    public boolean removeAll(Collection<?> collection) {
        boolean result = false;
        Iterator<?> it = iterator();
        while (it.hasNext()) {
            if (collection.contains(it.next())) {
                it.remove();
                result = true;
            }
        }
        return result;
    }
    /**
     * 覆盖并实现Collection中的retainAll方法
     */
    public boolean retainAll(Collection<?> collection) {
        boolean result = false;
        Iterator<?> it = iterator();
        while (it.hasNext()) {
            if (!collection.contains(it.next())) {
                it.remove();
                result = true;
            }
        }
        return result;
    }

    /**
     * 在这个类中,这个方法被声明为抽象的,必须由具体的Collection实现来实现。
     */
    public abstract int size();

    /**
     * 覆盖并实现Collection中的toArray方法
     */
    public Object[] toArray() {
        return toArrayList().toArray();
    }
    /**
     * 覆盖并实现Collection中的toArray方法
     */
    public <T> T[] toArray(T[] contents) {
        return toArrayList().toArray(contents);
    }

    /**
     * 私有方法,供AbstractCollection内部使用
     */
    @SuppressWarnings("unchecked")
    private ArrayList<Object> toArrayList() {
        ArrayList<Object> result = new ArrayList<Object>(size());
        for (E entry : this) {
            result.add(entry);
        }
        return result;
    }

    /**
     * 重写超类Object的toString方法,返回此集合的字符串形式
     */
    @Override
    public String toString() {
        if (isEmpty()) {
            return "[]";
        }

        StringBuilder buffer = new StringBuilder(size() * 16);
        buffer.append('[');
        Iterator<?> it = iterator();
        while (it.hasNext()) {
            Object next = it.next();
            if (next != this) {
                buffer.append(next);
            } else {
                buffer.append("(this Collection)");
            }
            if (it.hasNext()) {
                buffer.append(", ");
            }
        }
        buffer.append(']');
        return buffer.toString();
    }
}

AbstractCollection类总结:

  • 此类提供了 Collection 接口的骨干实现,从而最大限度地减少了实现此接口所需的工作。
  • 本类默认是不是可修改的,即不支持add,由于addAll依赖于add,所以addAll也是不支持的,要支持添加功能,就需要重写这个add方法
  • size,iterator这两个方法没有实现,所以要编写自己的collection,需要实现这两个方法即可
  • 本类没有对equals和hashCode进行重写,但是对toString进行了重写

AbstractList抽象类探索

/**
 * AbstractList是List接口的抽象实现,针对支持随机访问的后台存储进行了优化。 此实现不支持添加或替换。 一个子类必须实现抽象方法get()和size(),并创建一个可修改的List,这是必要的,以覆盖当前抛出UnsupportedOperationException的add()方法。
 */
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {

    private class SimpleListIterator implements Iterator<E> {
    }

    private final class FullListIterator extends SimpleListIterator implements ListIterator<E> {
    }

    private static final class SubAbstractListRandomAccess<E> extends
            SubAbstractList<E> implements RandomAccess {
    }

    private static class SubAbstractList<E> extends AbstractList<E> {
    }
    /**
    * 将指定的对象插入到此列表中的指定位置。 该对象被插入指定位置的任何先前元素之前。 如果位置等于此列表的大小,则会在最后添加该对象。
    * 希望支持添加功能的具体实现必须覆盖此方法。
    */
    public void add(int location, E object) {
        throw new UnsupportedOperationException();
    }
    /**
     * 添加元素,在尾部添加新的元素
     */
    @Override
    public boolean add(E object) {
        add(size(), object);
        return true;
    }
    /**
    * 将列表中指定的集合中的对象插入。 这些对象按照从集合的迭代器返回的顺序添加。
    */
    public boolean addAll(int location, Collection<? extends E> collection) {
        Iterator<? extends E> it = collection.iterator();
        while (it.hasNext()) {
            add(location++, it.next());
        }
        return !collection.isEmpty();
    }
    /**
     * Removes all elements from this list, leaving it empty.
     */
    @Override
    public void clear() {
        removeRange(0, size());
    }
    /**
     * 将指定的对象与此列表进行比较,如果相等则返回true。 当两个列表都以相同的顺序包含相同的对象时相等。
     */
    @Override
    public boolean equals(Object object) {
        if (this == object) {
            return true;
        }
        if (object instanceof List) {
            List<?> list = (List<?>) object;
            if (list.size() != size()) {
                return false;
            }

            Iterator<?> it1 = iterator(), it2 = list.iterator();
            while (it1.hasNext()) {
                Object e1 = it1.next(), e2 = it2.next();
                if (!(e1 == null ? e2 == null : e1.equals(e2))) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }

    /**
     * Returns the element at the specified location in this list.
     *
     * @param location
     *            the index of the element to return.
     * @return the element at the specified index.
     * @throws IndexOutOfBoundsException
     *             if {@code location < 0 || location >= size()}
     */
    public abstract E get(int location);

    /**
     * 返回此列表的哈希码。 哈希码是通过考虑每个元素的哈希码来计算的。
     */
    @Override
    public int hashCode() {
        int result = 1;
        Iterator<?> it = iterator();
        while (it.hasNext()) {
            Object object = it.next();
            result = (31 * result) + (object == null ? 0 : object.hashCode());
        }
        return result;
    }
    /**
     * 搜索指定对象的此列表,并返回第一次出现的索引。
     */
    public int indexOf(Object object) {
        ListIterator<?> it = listIterator();
        if (object != null) {
            while (it.hasNext()) {
                if (object.equals(it.next())) {
                    return it.previousIndex();
                }
            }
        } else {
            while (it.hasNext()) {
                if (it.next() == null) {
                    return it.previousIndex();
                }
            }
        }
        return -1;
    }
    /**
     * 返回此列表元素的迭代器。 元素按照与列表中相同的顺序进行迭代。
     */
    @Override
    public Iterator<E> iterator() {
        return new SimpleListIterator();
    }
    /**
     * 在此列表的元素上返回一个ListIterator。 元素以与列表中相同的顺序进行迭代。
     */
    public ListIterator<E> listIterator() {
        return listIterator(0);
    }
    /**
     * 返回此列表元素的列表迭代器。 元素按照与列表中相同的顺序进行迭代。 迭代从指定位置开始。
     */
    public ListIterator<E> listIterator(int location) {
        return new FullListIterator(location);
    }
    public E remove(int location) {
        throw new UnsupportedOperationException();
    }
    /**
     * 从开始到结束的索引减去一个指定范围内的对象。
     */
    protected void removeRange(int start, int end) {
        Iterator<?> it = listIterator(start);
        for (int i = start; i < end; i++) {
            it.next();
            it.remove();
        }
    }
    public E set(int location, E object) {
        throw new UnsupportedOperationException();
    }
    /**
     * 返回此列表的连续元素的一部分作为视图。 如果开始等于结束,则返回的视图将为零长度。 在返回的子列表中发生的任何更改都将反映到原始列表中,反之亦然。 所有由原始列表支持的可选操作也将由此子列表支持。
     */
    public List<E> subList(int start, int end) {
        if (start >= 0 && end <= size()) {
            if (start <= end) {
                if (this instanceof RandomAccess) {
                    return new SubAbstractListRandomAccess<E>(this, start, end);
                }
                return new SubAbstractList<E>(this, start, end);
            }
            throw new IllegalArgumentException();
        }
        throw new IndexOutOfBoundsException();
    }
}

猜你喜欢

转载自blog.csdn.net/u013277209/article/details/77773229