JavaSE集合框架-01-集合框架体系及表数据结构

一.Collection接口:

集合可以看做一种容器,即存储各种对象的容器,容器的实现方式有很多种(list,set),每种存储数据的方式(即数据结构)都有区别,但是它有很多共性的功能(增删改查等)。对集合的各种实现的共有方法进行抽取,可以得到一个金字塔形的集合框架,金字塔的最顶端就是Collection接口
Collection接口的子接口及实现类:

JavaSE集合框架-01-集合框架体系及表数据结构_第1张图片

Collection接口源码(去掉注释后)

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

    // Query Operations
    int size();

    boolean isEmpty();

    boolean contains(Object o);

    Iterator iterator();

    Object[] toArray();

     T[] toArray(T[] a);

    // Modification Operations

    boolean add(E e);

    boolean remove(Object o);

    // Bulk Operations

    boolean containsAll(Collection c);

    boolean addAll(Collection c);

    boolean removeAll(Collection c);

    boolean retainAll(Collection c);

    void clear();

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

    int hashCode();
}

JavaSEAPI中对Collection接口部分方法的解析

boolean contains(Object o)
如果此 collection 包含指定的元素,则返回 true。
boolean containsAll(Collection < ? > c)
如果此 collection 包含指定 collection 中的所有元素,则返回 true。
boolean equals(Object o)
比较此 collection 与指定对象是否相等。
int hashCode()
返回此 collection 的哈希码值。
Iterator iterator()
返回在此 collection 的元素上进行迭代的迭代器。

因为java中的集合数据结构都直接或间接的继承或实现了Collection接口。所以Collection接口中定义有集合数据结构普遍有的增删查方法

二.Iterator接口:

Iterator被称作迭代器,是一个接口,通过迭代的方式取集合中的元素,java中所有的集合数据结构都可以通过迭代的方式取出集合中的元素,所以迭代器是所有数据结构的都有的功能,对这项功能进行向上抽取,定义了一个超级接口Iterator接口
Iterator接口的定义也很好的体现了面向对象的理念,定义一个迭代器类,并将用于对集合元素的迭代方法都封装起来定义到这个迭代器类中,当需要对集合中的元素进行迭代时只需要获取这个类的对象,让后调用对象中的方法即可

import java.util.Iterator;

public interface Iterable {

    Iterator iterator();
}

Iterator接口源码(去掉注释)

public interface Iterator {

    boolean hasNext();

    E next();

    void remove();
}

JavaSEAPI中对Iterator接口方法的解析

boolean hasNext()
如果仍有元素可以迭代,则返回 true。
E next()
返回迭代的下一个元素。
void remove()
从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。

定义iterator接口的原因:
每一个集合都有自己的数据结构,都有特定的取出自己内部元素的方式。为了便于操作所有的容器,取出元素。将容器内部的取出方式按照一个统一的规则向外提供,这个规则就是Iterator接口
也就说,只要通过该接口就可以取出Collection集合中的元素,至于每一个具体的容器依据自己的数据结构,如何实现的具体取出细节,则不去考虑,这样就降低了取出元素操作和不同数据结构集合的耦合

三.List接口:

1.List集合框架简介:

有序的 Collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。与 set 不同,List列表允许重复的元素
List集合框架的特点:
1.有序(元素存入集合的顺序和取出的顺序一致)
2.元素都有索引
3.元素可以重复

List接口源码部分代码(去掉注释后)

package java.util;

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

    // 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 listIterator();

    ListIterator listIterator(int index);

    // View

    List subList(int fromIndex, int toIndex);
}

和Collection接口重复的一些方法没有列出,只列出了List接口特有的方法。可以看出,List接口对Collection的扩展方法中很多都是添加了用角标操作集合内的元素

2.List集合框架的常用实现类

2.1 List集合的数组实现ArrayList:

List 接口的数组的实现,大小可变。实现了所有列表操作(增删查,比较等List接口中有的方法),并允许包括 null 在内的所有元素。除了实现 List 接口外,此类还提供一些方法用来存储列表的数组的大小。
ArrayList类在功能上和Vector类非常相似,唯一不同的地方就是ArrayList类是不同步的,而Vector类则是同步的,Vector类已基本不用

ArrayList类的部分源码解析:

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
    ----------------------------------1.ArrayList类中定义的变量及构造方法-----------------------------
    //1.1 定义ArrayList的初始容量
    private static final int DEFAULT_CAPACITY = 10;
    private static final Object[] EMPTY_ELEMENTDATA = {};

    //1.2 定义一个Object对象数组用来存储List集合的元素
    private transient Object[] elementData;

    //1.3 定义int类型的size属性,记录集合的大小
    private int size;

    //1.4 空参构造函数(还有带参的构造函数,这里不一一显示)
    public ArrayList() {
        super();
        this.elementData = EMPTY_ELEMENTDATA;
    }
----------------------------------2.ArrayList类的特有方法,控制集合容量--------------------------------------
    //用于在存入元素的过程中集合容量不够用时扩大集合容量
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
-------------------------------------------3.ArrayList类的增删改查方法-----------------------------------------
    //ArrayList添加元素的方法
    public boolean add(E e) {
        //调用方法检查容量是否足够
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        //List集合存储元素和角标信息一起存储
        elementData[size++] = e;
        return true;
    }
    //ArrayList的查询方法
    public E get(int index) {
        rangeCheck(index);

        return elementData(index);
    }
    //ArrayList检查是否包含元素
    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }
    //ArrayList在指定角标地点添加元素
    public void add(int index, E element) {
        rangeCheckForAdd(index);

        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                size - index);
        elementData[index] = element;
        size++;
    }
    //ArrayList的更改元素方法
    public E set(int index, E element) {
        rangeCheck(index);
        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }
    //ArrayList的删除方法
    public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }

------------------------------------4.ArrayList类的增删改查方法的支持方法-------------------------------------------------


    public int indexOf(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }


-------------------------------------------5.ArrayList类的迭代器------------------------------------
    //5.1 返回一个实现了ListIterator接口的类的对象(一个迭代器对象),从指定的角标处开始迭代   
    public ListIterator listIterator(int index) {
        if (index < 0 || index > size)
            throw new IndexOutOfBoundsException("Index: "+index);
        return new ListItr(index);
    }
    //5.2 返回一个实现了ListIterator接口的类的对象(一个迭代器对象)
    public ListIterator listIterator() {
        return new ListItr(0);
    }

    //5.3 覆盖了AbstractList抽象类中iterator()方法,返回一个实现了Iterator接口的类的对象
    public Iterator iterator() {
        return new Itr();
    }

    //5.4 定义一个内部类,这个内部类实现了Iterator接口,根据数组列表的数据结构给出了迭代器的next,hasNext等方法的具体实现
    private class Itr implements Iterator<E> {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;

        //5.4.1 覆盖Iterator接口中的方法1:hasNext()
        public boolean hasNext() {
            return cursor != size;
        }
        //5.4.2 覆盖Iterator接口中的方法2:next()
        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }
        //5.4.3 覆盖Iterator接口中的方法3:remove()
        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }
    //5.5 定义一个内部类ListItr,继承了Itr类,实现了ListIterator接口,对Itr类进行了有关List集合的补充及扩展,如通过角标倒序(从后向前)迭代集合
    private class ListItr extends Itr implements ListIterator<E> {
        ListItr(int index) {
            super();
            cursor = index;
        }

        public boolean hasPrevious() {
            return cursor != 0;
        }

        public int nextIndex() {
            return cursor;
        }

        public int previousIndex() {
            return cursor - 1;
        }

        @SuppressWarnings("unchecked")
        public E previous() {
            checkForComodification();
            int i = cursor - 1;
            if (i < 0)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i;
            return (E) elementData[lastRet = i];
        }

        public void set(E e) {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.set(lastRet, e);
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

        public void add(E e) {
            checkForComodification();

            try {
                int i = cursor;
                ArrayList.this.add(i, e);
                cursor = i + 1;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
    }

ArrayList集合总结:

ArrayList实现数组数据结构的原因:
1.2 ArrayList定义一个Object对象数组用来存储List集合的元素,所以ArrayList集合对内部存储的元素的操作是对数组数据结构的操作,具有增删慢,查询快的特点

private transient Object[] elementData;

2.2 List集合的链表实现LinkedList:

LinkedList类的部分源码解析:

public class LinkedList<E>
        extends AbstractSequentialList<E>
        implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
-------------------------------------1.LinkedList类中定义的变量及构造方法----------------------------------
    //集合的长度
    transient int size = 0;
    //集合的第一个元素
    transient Node first;
    //集合的最后一个元素
    transient Node last;

    //构造方法
    public LinkedList() {
    }
-----------------------------2.LinkedList类实现链表数据结构的重要部分,静态内部类,节点类-----------------------
    //定义一个静态内部类--节点类,LinkedList将内部的每一个元素看做一个节点,即一个Node类的对象
    private static class Node<E> {
        E item;
        //每个节点都包保存有它的前一个节点和后一个节点的信息
        Node next;
        Node prev;
        //Node类的含参构造方法,共有3个参数,前一节点,元素对象,后一节点
        Node(Node prev, E element, Node next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

-------------------------------------3.LinkedList类的增删改查方法----------------------------------------
    //3.1 LinkedList在末尾添加元素
    public boolean add(E e) {
        linkLast(e);
        return true;
    }
    //3.2 LinkedList在指定角标地点添加元素
        public void add(int index, E element) {
        checkPositionIndex(index);

        if (index == size)
            linkLast(element);
        else
            linkBefore(element, node(index));
    }
    //3.3 LinkedList删除指定元素
    public boolean remove(Object o) {
        if (o == null) {
            for (Node x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }
    //3.4 LinkedList删除指定角标的元素
    public E remove(int index) {
        checkElementIndex(index);
        return unlink(node(index));
    }

---------------------------4.LinkedList类的增删改查方法的支持方法(经过抽取得到的)-----------------------------
    public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }

    public E set(int index, E element) {
        checkElementIndex(index);
        Node x = node(index);
        E oldVal = x.item;
        x.item = element;
        return oldVal;
    }

    private void checkElementIndex(int index) {
        if (!isElementIndex(index))
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

    private boolean isElementIndex(int index) {
        return index >= 0 && index < size;
    }

    void linkLast(E e) {
        final Node l = last;
        final Node newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }

    void linkBefore(E e, Node succ) {
        // assert succ != null;
        final Node pred = succ.prev;
        final Node newNode = new Node<>(pred, e, succ);
        succ.prev = newNode;
        if (pred == null)
            first = newNode;
        else
            pred.next = newNode;
        size++;
        modCount++;
    }

    E unlink(Node x) {
        // assert x != null;
        final E element = x.item;
        final Node next = x.next;
        final Node prev = x.prev;

        if (prev == null) {
            first = next;
        } else {
            prev.next = next;
            x.prev = null;
        }

        if (next == null) {
            last = prev;
        } else {
            next.prev = prev;
            x.next = null;
        }

        x.item = null;
        size--;
        modCount++;
        return element;
    }

    Node node(int index) {
        // assert isElementIndex(index);
        if (index < (size >> 1)) {
            Node x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        } else {
            Node x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }

---------------------------------5.LinkedList类的迭代器-------------------------------------------

    //返回一个
    public ListIterator listIterator(int index) {
        checkPositionIndex(index);
        return new ListItr(index);
    }

    private class ListItr implements ListIterator<E> {
        private Node lastReturned = null;
        private Node next;
        private int nextIndex;
        private int expectedModCount = modCount;

        ListItr(int index) {
            // assert isPositionIndex(index);
            next = (index == size) ? null : node(index);
            nextIndex = index;
        }

        public boolean hasNext() {
            return nextIndex < size;
        }

        public E next() {
            checkForComodification();
            if (!hasNext())
                throw new NoSuchElementException();

            lastReturned = next;
            next = next.next;
            nextIndex++;
            return lastReturned.item;
        }

        public boolean hasPrevious() {
            return nextIndex > 0;
        }

        public E previous() {
            checkForComodification();
            if (!hasPrevious())
                throw new NoSuchElementException();

            lastReturned = next = (next == null) ? last : next.prev;
            nextIndex--;
            return lastReturned.item;
        }

        public int nextIndex() {
            return nextIndex;
        }

        public int previousIndex() {
            return nextIndex - 1;
        }

        public void remove() {
            checkForComodification();
            if (lastReturned == null)
                throw new IllegalStateException();

            Node lastNext = lastReturned.next;
            unlink(lastReturned);
            if (next == lastReturned)
                next = lastNext;
            else
                nextIndex--;
            lastReturned = null;
            expectedModCount++;
        }

        public void set(E e) {
            if (lastReturned == null)
                throw new IllegalStateException();
            checkForComodification();
            lastReturned.item = e;
        }

        public void add(E e) {
            checkForComodification();
            lastReturned = null;
            if (next == null)
                linkLast(e);
            else
                linkBefore(e, next);
            nextIndex++;
            expectedModCount++;
        }

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }
    }

你可能感兴趣的:(JavaSE基础,算法/数据结构,Java基础知识总结)