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

来源:互联网 发布:sportsdt体育大数据 编辑:程序博客网 时间:2024/06/01 13:35

一.Collection接口:

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

这里写图片描述

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

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);    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<T> {    Iterator<T> iterator();}

Iterator接口源码(去掉注释)

public interface Iterator<E> {    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<E> listIterator();    ListIterator<E> listIterator(int index);    // View    List<E> 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<E> listIterator(int index) {        if (index < 0 || index > size)            throw new IndexOutOfBoundsException("Index: "+index);        return new ListItr(index);    }    //5.2 返回一个实现了ListIterator接口的类的对象(一个迭代器对象)    public ListIterator<E> listIterator() {        return new ListItr(0);    }    //5.3 覆盖了AbstractList抽象类中iterator()方法,返回一个实现了Iterator接口的类的对象    public Iterator<E> 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<E> first;    //集合的最后一个元素    transient Node<E> last;    //构造方法    public LinkedList() {    }-----------------------------2.LinkedList类实现链表数据结构的重要部分,静态内部类,节点类-----------------------    //定义一个静态内部类--节点类,LinkedList将内部的每一个元素看做一个节点,即一个Node类的对象    private static class Node<E> {        E item;        //每个节点都包保存有它的前一个节点和后一个节点的信息        Node<E> next;        Node<E> prev;        //Node类的含参构造方法,共有3个参数,前一节点,元素对象,后一节点        Node(Node<E> prev, E element, Node<E> 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<E> x = first; x != null; x = x.next) {                if (x.item == null) {                    unlink(x);                    return true;                }            }        } else {            for (Node<E> 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<E> 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<E> l = last;        final Node<E> newNode = new Node<>(l, e, null);        last = newNode;        if (l == null)            first = newNode;        else            l.next = newNode;        size++;        modCount++;    }    void linkBefore(E e, Node<E> succ) {        // assert succ != null;        final Node<E> pred = succ.prev;        final Node<E> newNode = new Node<>(pred, e, succ);        succ.prev = newNode;        if (pred == null)            first = newNode;        else            pred.next = newNode;        size++;        modCount++;    }    E unlink(Node<E> x) {        // assert x != null;        final E element = x.item;        final Node<E> next = x.next;        final Node<E> 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<E> node(int index) {        // assert isElementIndex(index);        if (index < (size >> 1)) {            Node<E> x = first;            for (int i = 0; i < index; i++)                x = x.next;            return x;        } else {            Node<E> x = last;            for (int i = size - 1; i > index; i--)                x = x.prev;            return x;        }    }---------------------------------5.LinkedList类的迭代器-------------------------------------------    //返回一个    public ListIterator<E> listIterator(int index) {        checkPositionIndex(index);        return new ListItr(index);    }    private class ListItr implements ListIterator<E> {        private Node<E> lastReturned = null;        private Node<E> 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<E> 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();        }    }