常用数据结构底层实现及源码

ArrayList、HashMap、Collection、LinkedList、Redis 底层实现及源码

Redis

Redis简介

Redis是一种key/value型数据库,其中,每个key和value都是使用对象表示的。

SET message "Hello"

其中,字符串 “message” 这个对象 就是 key , “Hello” 这个对象 就是 value

Redis有5种对象的类型

类型常量 小写 对象名称
REDIS_STRING string 字符串对象
REDIS_LIST list 列表对象
REDIS_HASH hash 哈希对象
REDIS_SET set 集合对象
REDIS_ZSET zset 有序集合对象

Redis对象底层数据结构

编码常量 数据结构
int long类型的整数
embstr embstr编码的简单动态字符串
raw 简单动态字符串
ht 字典
linkedlist 双端链表
ziplist 压缩列表
intset 整数集合
skiplist 跳跃表和字典

字符串对象

字符串对象的编码可以是int、raw、embstr

如果字符串对象的长度小于39字节,就用embstr

否则用传统的raw对象

# define REDIS_ENCODING_EMBSTR_SIZE_LIMIT 39
robj *createStringObject(char *ptr, size_t len) {
    if (len <= REDIS_ENCODING_EMBSTR_SIZE_LIMIT)
        return createEmbeddedStringObject(ptr,len);
    else
        return createRawStringObject(ptr,len);
}  

embstr的优点:

  • 创建只需分配一次内存,raw为两次
  • 释放内存也是一次
  • embstr的objet和sds放在一起,更好地利用缓存带来的优势

列表对象

列表对象的编码可以是 ziplist or LinkedList

ziplist 是一种压缩链表,好处是更能节省内存空间,存储的内容都是在连续的内存区域中的

LinkedList是一种双向链表,没增加一个node,都要重新分配一个内存


哈希对象

哈希对象的底层实现用ziplist or hashtable

ziplist : 对象数目不多且内容不大,这种方式效率很高

HashTable由dict这个结构实现


集合对象

集合对象编码可以是 intset or HashTable


有序集合对象

编码一种是 ziplist ,一种是skipList 与 dict 的结合

ziplist作为集合和作为哈希对象是一样的,member和score顺序存放。按照score从小到大顺序排列。它的结构不再复述。

skiplist是一种跳跃表,它实现了有序集合中的快速查找,在大多数情况下它的速度都可以和平衡树差不多。但它的实现比较简单,可以作为平衡树的替代品。


ArrayList

ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长(1.5+1)。

非线程安全

源码:

package java.util;    

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
    // 序列版本号
    private static final long serialVersionUID = 8683452581122892189L;    

    // ArrayList基于该数组实现,用该数组保存数据
    private transient Object[] elementData;    

    // ArrayList中实际数据的数量
    private int size;    

    // ArrayList带容量大小的构造函数。
    public ArrayList(int initialCapacity) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        // 新建一个数组
        this.elementData = new Object[initialCapacity];
    }    

    // ArrayList无参构造函数。默认容量是10。
    public ArrayList() {
        this(10);
    }    

    // 创建一个包含collection的ArrayList
    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        size = elementData.length;
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    }    

    // 将当前容量值设为实际元素个数
    public void trimToSize() {
        modCount++;
        int oldCapacity = elementData.length;
        if (size < oldCapacity) {
            elementData = Arrays.copyOf(elementData, size);
        }
    }    

    // 确定ArrarList的容量。
    // 若ArrayList的容量不足以容纳当前的全部元素,设置 新的容量=“(原始容量x3)/2 + 1”
    public void ensureCapacity(int minCapacity) {
        // 将“修改统计数”+1,该变量主要是用来实现fail-fast机制的
        modCount++;
        int oldCapacity = elementData.length;
        // 若当前容量不足以容纳当前的元素个数,设置 新的容量=“(原始容量x3)/2 + 1”
        if (minCapacity > oldCapacity) {
            Object oldData[] = elementData;
            int newCapacity = (oldCapacity * 3)/2 + 1;
            //如果还不够,则直接将minCapacity设置为当前容量
            if (newCapacity < minCapacity)
                newCapacity = minCapacity;
            elementData = Arrays.copyOf(elementData, newCapacity);
        }
    }    

    // 添加元素e
    public boolean add(E e) {
        // 确定ArrayList的容量大小
        ensureCapacity(size + 1);  // Increments modCount!!
        // 添加e到ArrayList中
        elementData[size++] = e;
        return true;
    }    

    // 返回ArrayList的实际大小
    public int size() {
        return size;
    }    

    // ArrayList是否包含Object(o)
    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }    

    //返回ArrayList是否为空
    public boolean isEmpty() {
        return size == 0;
    }    

    // 正向查找,返回元素的索引值
    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;
        }    

    // 反向查找(从数组末尾向开始查找),返回元素(o)的索引值
    public int lastIndexOf(Object o) {
        if (o == null) {
            for (int i = size-1; i >= 0; i--)
            if (elementData[i]==null)
                return i;
        } else {
            for (int i = size-1; i >= 0; i--)
            if (o.equals(elementData[i]))
                return i;
        }
        return -1;
    }    

    // 返回ArrayList的Object数组
    public Object[] toArray() {
        return Arrays.copyOf(elementData, size);
    }    

    // 返回ArrayList元素组成的数组
    public <T> T[] toArray(T[] a) {
        // 若数组a的大小 < ArrayList的元素个数;
        // 则新建一个T[]数组,数组大小是“ArrayList的元素个数”,并将“ArrayList”全部拷贝到新数组中
        if (a.length < size)
            return (T[]) Arrays.copyOf(elementData, size, a.getClass());    

        // 若数组a的大小 >= ArrayList的元素个数;
        // 则将ArrayList的全部元素都拷贝到数组a中。
        System.arraycopy(elementData, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }    

    // 获取index位置的元素值
    public E get(int index) {
        RangeCheck(index);    

        return (E) elementData[index];
    }    

    // 设置index位置的值为element
    public E set(int index, E element) {
        RangeCheck(index);    

        E oldValue = (E) elementData[index];
        elementData[index] = element;
        return oldValue;
    }    

    // 将e添加到ArrayList中
    public boolean add(E e) {
        ensureCapacity(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }    

    // 将e添加到ArrayList的指定位置
    public void add(int index, E element) {
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(
            "Index: "+index+", Size: "+size);    

        ensureCapacity(size+1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
             size - index);
        elementData[index] = element;
        size++;
    }    

    // 删除ArrayList指定位置的元素
    public E remove(int index) {
        RangeCheck(index);    

        modCount++;
        E oldValue = (E) elementData[index];    

        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                 numMoved);
        elementData[--size] = null; // Let gc do its work    

        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;
    }    

    // 快速删除第index个元素
    private void fastRemove(int index) {
        modCount++;
        int numMoved = size - index - 1;
        // 从"index+1"开始,用后面的元素替换前面的元素。
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        // 将最后一个元素设为null
        elementData[--size] = null; // Let gc do its work
    }    

    // 删除元素
    public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
            if (elementData[index] == null) {
                fastRemove(index);
            return true;
            }
        } else {
            // 便利ArrayList,找到“元素o”,则删除,并返回true。
            for (int index = 0; index < size; index++)
            if (o.equals(elementData[index])) {
                fastRemove(index);
            return true;
            }
        }
        return false;
    }    

    // 清空ArrayList,将全部的元素设为null
    public void clear() {
        modCount++;    

        for (int i = 0; i < size; i++)
            elementData[i] = null;    

        size = 0;
    }    

    // 将集合c追加到ArrayList中
    public boolean addAll(Collection<? extends E> c) {
        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacity(size + numNew);  // Increments modCount
        System.arraycopy(a, 0, elementData, size, numNew);
        size += numNew;
        return numNew != 0;
    }    

    // 从index位置开始,将集合c添加到ArrayList
    public boolean addAll(int index, Collection<? extends E> c) {
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(
            "Index: " + index + ", Size: " + size);    

        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacity(size + numNew);  // Increments modCount    

        int numMoved = size - index;
        if (numMoved > 0)
            System.arraycopy(elementData, index, elementData, index + numNew,
                 numMoved);    

        System.arraycopy(a, 0, elementData, index, numNew);
        size += numNew;
        return numNew != 0;
    }    

    // 删除fromIndex到toIndex之间的全部元素。
    protected void removeRange(int fromIndex, int toIndex) {
    modCount++;
    int numMoved = size - toIndex;
        System.arraycopy(elementData, toIndex, elementData, fromIndex,
                         numMoved);    

    // Let gc do its work
    int newSize = size - (toIndex-fromIndex);
    while (size != newSize)
        elementData[--size] = null;
    }    

    private void RangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException(
        "Index: "+index+", Size: "+size);
    }    

    // 克隆函数
    public Object clone() {
        try {
            ArrayList<E> v = (ArrayList<E>) super.clone();
            // 将当前ArrayList的全部元素拷贝到v中
            v.elementData = Arrays.copyOf(elementData, size);
            v.modCount = 0;
            return v;
        } catch (CloneNotSupportedException e) {
            // this shouldn‘t happen, since we are Cloneable
            throw new InternalError();
        }
    }    

    // java.io.Serializable的写入函数
    // 将ArrayList的“容量,所有的元素值”都写入到输出流中
    private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException{
    // Write out element count, and any hidden stuff
    int expectedModCount = modCount;
    s.defaultWriteObject();    

        // 写入“数组的容量”
        s.writeInt(elementData.length);    

    // 写入“数组的每一个元素”
    for (int i=0; i<size; i++)
            s.writeObject(elementData[i]);    

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

    }    

    // java.io.Serializable的读取函数:根据写入方式读出
    // 先将ArrayList的“容量”读出,然后将“所有的元素值”读出
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        // Read in size, and any hidden stuff
        s.defaultReadObject();    

        // 从输入流中读取ArrayList的“容量”
        int arrayLength = s.readInt();
        Object[] a = elementData = new Object[arrayLength];    

        // 从输入流中将“所有的元素值”读出
        for (int i=0; i<size; i++)
            a[i] = s.readObject();
    }
}  

HashMap

HashMap是基于哈希表实现,每一个元素都是一个key-value对,其内部通过单链表解决冲突问题,容量不足时,会自动增长。

非线程安全,只是用于单线程环境下,多线程用concurrentHashMap

实现了Serializable接口,因此支持序列化,实现了Cloneable接口,能被克隆。

源码:

package java.util;
import java.io.*;    

public class HashMap<K,V>
    extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable
{    

    // 默认的初始容量(容量为HashMap中槽的数目)是16,且实际容量必须是2的整数次幂。
    static final int DEFAULT_INITIAL_CAPACITY = 16;    

    // 最大容量(必须是2的幂且小于2的30次方,传入容量过大将被这个值替换)
    static final int MAXIMUM_CAPACITY = 1 << 30;    

    // 默认加载因子为0.75
    static final float DEFAULT_LOAD_FACTOR = 0.75f;    

    // 存储数据的Entry数组,长度是2的幂。
    // HashMap采用链表法解决冲突,每一个Entry本质上是一个单向链表
    transient Entry[] table;    

    // HashMap的底层数组中已用槽的数量
    transient int size;    

    // HashMap的阈值,用于判断是否需要调整HashMap的容量(threshold = 容量*加载因子)
    int threshold;    

    // 加载因子实际大小
    final float loadFactor;    

    // HashMap被改变的次数
    transient volatile int modCount;    

    // 指定“容量大小”和“加载因子”的构造函数
    public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        // HashMap的最大容量只能是MAXIMUM_CAPACITY
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        //加载因此不能小于0
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);    

        // 找出“大于initialCapacity”的最小的2的幂
        int capacity = 1;
        while (capacity < initialCapacity)
            capacity <<= 1;    

        // 设置“加载因子”
        this.loadFactor = loadFactor;
        // 设置“HashMap阈值”,当HashMap中存储数据的数量达到threshold时,就需要将HashMap的容量加倍。
        threshold = (int)(capacity * loadFactor);
        // 创建Entry数组,用来保存数据
        table = new Entry[capacity];
        init();
    }    

    // 指定“容量大小”的构造函数
    public HashMap(int initialCapacity) {
        this(initialCapacity, DEFAULT_LOAD_FACTOR);
    }    

    // 默认构造函数。
    public HashMap() {
        // 设置“加载因子”为默认加载因子0.75
        this.loadFactor = DEFAULT_LOAD_FACTOR;
        // 设置“HashMap阈值”,当HashMap中存储数据的数量达到threshold时,就需要将HashMap的容量加倍。
        threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
        // 创建Entry数组,用来保存数据
        table = new Entry[DEFAULT_INITIAL_CAPACITY];
        init();
    }    

    // 包含“子Map”的构造函数
    public HashMap(Map<? extends K, ? extends V> m) {
        this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
                      DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
        // 将m中的全部元素逐个添加到HashMap中
        putAllForCreate(m);
    }    

    //求hash值的方法,重新计算hash值
    static int hash(int h) {
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }    

    // 返回h在数组中的索引值,这里用&代替取模,旨在提升效率
    // h & (length-1)保证返回值的小于length
    static int indexFor(int h, int length) {
        return h & (length-1);
    }    

    public int size() {
        return size;
    }    

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

    // 获取key对应的value
    public V get(Object key) {
        if (key == null)
            return getForNullKey();
        // 获取key的hash值
        int hash = hash(key.hashCode());
        // 在“该hash值对应的链表”上查找“键值等于key”的元素
        for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
            //判断key是否相同
            if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
                return e.value;
        }
        //没找到则返回null
        return null;
    }    

    // 获取“key为null”的元素的值
    // HashMap将“key为null”的元素存储在table[0]位置,但不一定是该链表的第一个位置!
    private V getForNullKey() {
        for (Entry<K,V> e = table[0]; e != null; e = e.next) {
            if (e.key == null)
                return e.value;
        }
        return null;
    }    

    // HashMap是否包含key
    public boolean containsKey(Object key) {
        return getEntry(key) != null;
    }    

    // 返回“键为key”的键值对
    final Entry<K,V> getEntry(Object key) {
        // 获取哈希值
        // HashMap将“key为null”的元素存储在table[0]位置,“key不为null”的则调用hash()计算哈希值
        int hash = (key == null) ? 0 : hash(key.hashCode());
        // 在“该hash值对应的链表”上查找“键值等于key”的元素
        for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
            if (e.hash == hash &&
                ((k = e.key) == key || (key != null && key.equals(k))))
                return e;
        }
        return null;
    }    

    // 将“key-value”添加到HashMap中
    public V put(K key, V value) {
        // 若“key为null”,则将该键值对添加到table[0]中。
        if (key == null)
            return putForNullKey(value);
        // 若“key不为null”,则计算该key的哈希值,然后将其添加到该哈希值对应的链表中。
        int hash = hash(key.hashCode());
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            // 若“该key”对应的键值对已经存在,则用新的value取代旧的value。然后退出!
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }    

        // 若“该key”对应的键值对不存在,则将“key-value”添加到table中
        modCount++;
        //将key-value添加到table[i]处
        addEntry(hash, key, value, i);
        return null;
    }    

    // putForNullKey()的作用是将“key为null”键值对添加到table[0]位置
    private V putForNullKey(V value) {
        for (Entry<K,V> e = table[0]; e != null; e = e.next) {
            if (e.key == null) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }
        // 如果没有存在key为null的键值对,则直接题阿见到table[0]处!
        modCount++;
        addEntry(0, null, value, 0);
        return null;
    }    

    // 创建HashMap对应的“添加方法”,
    // 它和put()不同。putForCreate()是内部方法,它被构造函数等调用,用来创建HashMap
    // 而put()是对外提供的往HashMap中添加元素的方法。
    private void putForCreate(K key, V value) {
        int hash = (key == null) ? 0 : hash(key.hashCode());
        int i = indexFor(hash, table.length);    

        // 若该HashMap表中存在“键值等于key”的元素,则替换该元素的value值
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash &&
                ((k = e.key) == key || (key != null && key.equals(k)))) {
                e.value = value;
                return;
            }
        }    

        // 若该HashMap表中不存在“键值等于key”的元素,则将该key-value添加到HashMap中
        createEntry(hash, key, value, i);
    }    

    // 将“m”中的全部元素都添加到HashMap中。
    // 该方法被内部的构造HashMap的方法所调用。
    private void putAllForCreate(Map<? extends K, ? extends V> m) {
        // 利用迭代器将元素逐个添加到HashMap中
        for (Iterator<? extends Map.Entry<? extends K, ? extends V>> i = m.entrySet().iterator(); i.hasNext(); ) {
            Map.Entry<? extends K, ? extends V> e = i.next();
            putForCreate(e.getKey(), e.getValue());
        }
    }    

    // 重新调整HashMap的大小,newCapacity是调整后的容量
    void resize(int newCapacity) {
        Entry[] oldTable = table;
        int oldCapacity = oldTable.length;
        //如果就容量已经达到了最大值,则不能再扩容,直接返回
        if (oldCapacity == MAXIMUM_CAPACITY) {
            threshold = Integer.MAX_VALUE;
            return;
        }    

        // 新建一个HashMap,将“旧HashMap”的全部元素添加到“新HashMap”中,
        // 然后,将“新HashMap”赋值给“旧HashMap”。
        Entry[] newTable = new Entry[newCapacity];
        transfer(newTable);
        table = newTable;
        threshold = (int)(newCapacity * loadFactor);
    }    

    // 将HashMap中的全部元素都添加到newTable中
    void transfer(Entry[] newTable) {
        Entry[] src = table;
        int newCapacity = newTable.length;
        for (int j = 0; j < src.length; j++) {
            Entry<K,V> e = src[j];
            if (e != null) {
                src[j] = null;
                do {
                    Entry<K,V> next = e.next;
                    int i = indexFor(e.hash, newCapacity);
                    e.next = newTable[i];
                    newTable[i] = e;
                    e = next;
                } while (e != null);
            }
        }
    }    

    // 将"m"的全部元素都添加到HashMap中
    public void putAll(Map<? extends K, ? extends V> m) {
        // 有效性判断
        int numKeysToBeAdded = m.size();
        if (numKeysToBeAdded == 0)
            return;    

        // 计算容量是否足够,
        // 若“当前阀值容量 < 需要的容量”,则将容量x2。
        if (numKeysToBeAdded > threshold) {
            int targetCapacity = (int)(numKeysToBeAdded / loadFactor + 1);
            if (targetCapacity > MAXIMUM_CAPACITY)
                targetCapacity = MAXIMUM_CAPACITY;
            int newCapacity = table.length;
            while (newCapacity < targetCapacity)
                newCapacity <<= 1;
            if (newCapacity > table.length)
                resize(newCapacity);
        }    

        // 通过迭代器,将“m”中的元素逐个添加到HashMap中。
        for (Iterator<? extends Map.Entry<? extends K, ? extends V>> i = m.entrySet().iterator(); i.hasNext(); ) {
            Map.Entry<? extends K, ? extends V> e = i.next();
            put(e.getKey(), e.getValue());
        }
    }    

    // 删除“键为key”元素
    public V remove(Object key) {
        Entry<K,V> e = removeEntryForKey(key);
        return (e == null ? null : e.value);
    }    

    // 删除“键为key”的元素
    final Entry<K,V> removeEntryForKey(Object key) {
        // 获取哈希值。若key为null,则哈希值为0;否则调用hash()进行计算
        int hash = (key == null) ? 0 : hash(key.hashCode());
        int i = indexFor(hash, table.length);
        Entry<K,V> prev = table[i];
        Entry<K,V> e = prev;    

        // 删除链表中“键为key”的元素
        // 本质是“删除单向链表中的节点”
        while (e != null) {
            Entry<K,V> next = e.next;
            Object k;
            if (e.hash == hash &&
                ((k = e.key) == key || (key != null && key.equals(k)))) {
                modCount++;
                size--;
                if (prev == e)
                    table[i] = next;
                else
                    prev.next = next;
                e.recordRemoval(this);
                return e;
            }
            prev = e;
            e = next;
        }    

        return e;
    }    

    // 删除“键值对”
    final Entry<K,V> removeMapping(Object o) {
        if (!(o instanceof Map.Entry))
            return null;    

        Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
        Object key = entry.getKey();
        int hash = (key == null) ? 0 : hash(key.hashCode());
        int i = indexFor(hash, table.length);
        Entry<K,V> prev = table[i];
        Entry<K,V> e = prev;    

        // 删除链表中的“键值对e”
        // 本质是“删除单向链表中的节点”
        while (e != null) {
            Entry<K,V> next = e.next;
            if (e.hash == hash && e.equals(entry)) {
                modCount++;
                size--;
                if (prev == e)
                    table[i] = next;
                else
                    prev.next = next;
                e.recordRemoval(this);
                return e;
            }
            prev = e;
            e = next;
        }    

        return e;
    }    

    // 清空HashMap,将所有的元素设为null
    public void clear() {
        modCount++;
        Entry[] tab = table;
        for (int i = 0; i < tab.length; i++)
            tab[i] = null;
        size = 0;
    }    

    // 是否包含“值为value”的元素
    public boolean containsValue(Object value) {
    // 若“value为null”,则调用containsNullValue()查找
    if (value == null)
            return containsNullValue();    

    // 若“value不为null”,则查找HashMap中是否有值为value的节点。
    Entry[] tab = table;
        for (int i = 0; i < tab.length ; i++)
            for (Entry e = tab[i] ; e != null ; e = e.next)
                if (value.equals(e.value))
                    return true;
    return false;
    }    

    // 是否包含null值
    private boolean containsNullValue() {
    Entry[] tab = table;
        for (int i = 0; i < tab.length ; i++)
            for (Entry e = tab[i] ; e != null ; e = e.next)
                if (e.value == null)
                    return true;
    return false;
    }    

    // 克隆一个HashMap,并返回Object对象
    public Object clone() {
        HashMap<K,V> result = null;
        try {
            result = (HashMap<K,V>)super.clone();
        } catch (CloneNotSupportedException e) {
            // assert false;
        }
        result.table = new Entry[table.length];
        result.entrySet = null;
        result.modCount = 0;
        result.size = 0;
        result.init();
        // 调用putAllForCreate()将全部元素添加到HashMap中
        result.putAllForCreate(this);    

        return result;
    }    

    // Entry是单向链表。
    // 它是 “HashMap链式存储法”对应的链表。
    // 它实现了Map.Entry 接口,即实现getKey(), getValue(), setValue(V value), equals(Object o), hashCode()这些函数
    static class Entry<K,V> implements Map.Entry<K,V> {
        final K key;
        V value;
        // 指向下一个节点
        Entry<K,V> next;
        final int hash;    

        // 构造函数。
        // 输入参数包括"哈希值(h)", "键(k)", "值(v)", "下一节点(n)"
        Entry(int h, K k, V v, Entry<K,V> n) {
            value = v;
            next = n;
            key = k;
            hash = h;
        }    

        public final K getKey() {
            return key;
        }    

        public final V getValue() {
            return value;
        }    

        public final V setValue(V newValue) {
            V oldValue = value;
            value = newValue;
            return oldValue;
        }    

        // 判断两个Entry是否相等
        // 若两个Entry的“key”和“value”都相等,则返回true。
        // 否则,返回false
        public final boolean equals(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry e = (Map.Entry)o;
            Object k1 = getKey();
            Object k2 = e.getKey();
            if (k1 == k2 || (k1 != null && k1.equals(k2))) {
                Object v1 = getValue();
                Object v2 = e.getValue();
                if (v1 == v2 || (v1 != null && v1.equals(v2)))
                    return true;
            }
            return false;
        }    

        // 实现hashCode()
        public final int hashCode() {
            return (key==null   ? 0 : key.hashCode()) ^
                   (value==null ? 0 : value.hashCode());
        }    

        public final String toString() {
            return getKey() + "=" + getValue();
        }    

        // 当向HashMap中添加元素时,绘调用recordAccess()。
        // 这里不做任何处理
        void recordAccess(HashMap<K,V> m) {
        }    

        // 当从HashMap中删除元素时,绘调用recordRemoval()。
        // 这里不做任何处理
        void recordRemoval(HashMap<K,V> m) {
        }
    }    

    // 新增Entry。将“key-value”插入指定位置,bucketIndex是位置索引。
    void addEntry(int hash, K key, V value, int bucketIndex) {
        // 保存“bucketIndex”位置的值到“e”中
        Entry<K,V> e = table[bucketIndex];
        // 设置“bucketIndex”位置的元素为“新Entry”,
        // 设置“e”为“新Entry的下一个节点”
        table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
        // 若HashMap的实际大小 不小于 “阈值”,则调整HashMap的大小
        if (size++ >= threshold)
            resize(2 * table.length);
    }    

    // 创建Entry。将“key-value”插入指定位置。
    void createEntry(int hash, K key, V value, int bucketIndex) {
        // 保存“bucketIndex”位置的值到“e”中
        Entry<K,V> e = table[bucketIndex];
        // 设置“bucketIndex”位置的元素为“新Entry”,
        // 设置“e”为“新Entry的下一个节点”
        table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
        size++;
    }    

    // HashIterator是HashMap迭代器的抽象出来的父类,实现了公共了函数。
    // 它包含“key迭代器(KeyIterator)”、“Value迭代器(ValueIterator)”和“Entry迭代器(EntryIterator)”3个子类。
    private abstract class HashIterator<E> implements Iterator<E> {
        // 下一个元素
        Entry<K,V> next;
        // expectedModCount用于实现fast-fail机制。
        int expectedModCount;
        // 当前索引
        int index;
        // 当前元素
        Entry<K,V> current;    

        HashIterator() {
            expectedModCount = modCount;
            if (size > 0) { // advance to first entry
                Entry[] t = table;
                // 将next指向table中第一个不为null的元素。
                // 这里利用了index的初始值为0,从0开始依次向后遍历,直到找到不为null的元素就退出循环。
                while (index < t.length && (next = t[index++]) == null)
                    ;
            }
        }    

        public final boolean hasNext() {
            return next != null;
        }    

        // 获取下一个元素
        final Entry<K,V> nextEntry() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            Entry<K,V> e = next;
            if (e == null)
                throw new NoSuchElementException();    

            // 注意!!!
            // 一个Entry就是一个单向链表
            // 若该Entry的下一个节点不为空,就将next指向下一个节点;
            // 否则,将next指向下一个链表(也是下一个Entry)的不为null的节点。
            if ((next = e.next) == null) {
                Entry[] t = table;
                while (index < t.length && (next = t[index++]) == null)
                    ;
            }
            current = e;
            return e;
        }    

        // 删除当前元素
        public void remove() {
            if (current == null)
                throw new IllegalStateException();
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            Object k = current.key;
            current = null;
            HashMap.this.removeEntryForKey(k);
            expectedModCount = modCount;
        }    

    }    

    // value的迭代器
    private final class ValueIterator extends HashIterator<V> {
        public V next() {
            return nextEntry().value;
        }
    }    

    // key的迭代器
    private final class KeyIterator extends HashIterator<K> {
        public K next() {
            return nextEntry().getKey();
        }
    }    

    // Entry的迭代器
    private final class EntryIterator extends HashIterator<Map.Entry<K,V>> {
        public Map.Entry<K,V> next() {
            return nextEntry();
        }
    }    

    // 返回一个“key迭代器”
    Iterator<K> newKeyIterator()   {
        return new KeyIterator();
    }
    // 返回一个“value迭代器”
    Iterator<V> newValueIterator()   {
        return new ValueIterator();
    }
    // 返回一个“entry迭代器”
    Iterator<Map.Entry<K,V>> newEntryIterator()   {
        return new EntryIterator();
    }    

    // HashMap的Entry对应的集合
    private transient Set<Map.Entry<K,V>> entrySet = null;    

    // 返回“key的集合”,实际上返回一个“KeySet对象”
    public Set<K> keySet() {
        Set<K> ks = keySet;
        return (ks != null ? ks : (keySet = new KeySet()));
    }    

    // Key对应的集合
    // KeySet继承于AbstractSet,说明该集合中没有重复的Key。
    private final class KeySet extends AbstractSet<K> {
        public Iterator<K> iterator() {
            return newKeyIterator();
        }
        public int size() {
            return size;
        }
        public boolean contains(Object o) {
            return containsKey(o);
        }
        public boolean remove(Object o) {
            return HashMap.this.removeEntryForKey(o) != null;
        }
        public void clear() {
            HashMap.this.clear();
        }
    }    

    // 返回“value集合”,实际上返回的是一个Values对象
    public Collection<V> values() {
        Collection<V> vs = values;
        return (vs != null ? vs : (values = new Values()));
    }    

    // “value集合”
    // Values继承于AbstractCollection,不同于“KeySet继承于AbstractSet”,
    // Values中的元素能够重复。因为不同的key可以指向相同的value。
    private final class Values extends AbstractCollection<V> {
        public Iterator<V> iterator() {
            return newValueIterator();
        }
        public int size() {
            return size;
        }
        public boolean contains(Object o) {
            return containsValue(o);
        }
        public void clear() {
            HashMap.this.clear();
        }
    }    

    // 返回“HashMap的Entry集合”
    public Set<Map.Entry<K,V>> entrySet() {
        return entrySet0();
    }    

    // 返回“HashMap的Entry集合”,它实际是返回一个EntrySet对象
    private Set<Map.Entry<K,V>> entrySet0() {
        Set<Map.Entry<K,V>> es = entrySet;
        return es != null ? es : (entrySet = new EntrySet());
    }    

    // EntrySet对应的集合
    // EntrySet继承于AbstractSet,说明该集合中没有重复的EntrySet。
    private final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
        public Iterator<Map.Entry<K,V>> iterator() {
            return newEntryIterator();
        }
        public boolean contains(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry<K,V> e = (Map.Entry<K,V>) o;
            Entry<K,V> candidate = getEntry(e.getKey());
            return candidate != null && candidate.equals(e);
        }
        public boolean remove(Object o) {
            return removeMapping(o) != null;
        }
        public int size() {
            return size;
        }
        public void clear() {
            HashMap.this.clear();
        }
    }    

    // java.io.Serializable的写入函数
    // 将HashMap的“总的容量,实际容量,所有的Entry”都写入到输出流中
    private void writeObject(java.io.ObjectOutputStream s)
        throws IOException
    {
        Iterator<Map.Entry<K,V>> i =
            (size > 0) ? entrySet0().iterator() : null;    

        // Write out the threshold, loadfactor, and any hidden stuff
        s.defaultWriteObject();    

        // Write out number of buckets
        s.writeInt(table.length);    

        // Write out size (number of Mappings)
        s.writeInt(size);    

        // Write out keys and values (alternating)
        if (i != null) {
            while (i.hasNext()) {
            Map.Entry<K,V> e = i.next();
            s.writeObject(e.getKey());
            s.writeObject(e.getValue());
            }
        }
    }    

    private static final long serialVersionUID = 362498820763181265L;    

    // java.io.Serializable的读取函数:根据写入方式读出
    // 将HashMap的“总的容量,实际容量,所有的Entry”依次读出
    private void readObject(java.io.ObjectInputStream s)
         throws IOException, ClassNotFoundException
    {
        // Read in the threshold, loadfactor, and any hidden stuff
        s.defaultReadObject();    

        // Read in number of buckets and allocate the bucket array;
        int numBuckets = s.readInt();
        table = new Entry[numBuckets];    

        init();  // Give subclass a chance to do its thing.    

        // Read in size (number of Mappings)
        int size = s.readInt();    

        // Read the keys and values, and put the mappings in the HashMap
        for (int i=0; i<size; i++) {
            K key = (K) s.readObject();
            V value = (V) s.readObject();
            putForCreate(key, value);
        }
    }    

    // 返回“HashMap总的容量”
    int   capacity()     { return table.length; }
    // 返回“HashMap的加载因子”
    float loadFactor()   { return loadFactor;   }
}   

HashTable

基于哈希表实现,每个元素都是key-value对,内部通过单链表解决冲突问题,容量不足时,自动增长

是线程安全的,能用于多线程

实现了Serializable接口,支持序列号

实现了Cloneable接口,能被克隆

package java.util;
import java.io.*;    

public class Hashtable<K,V>
    extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable {    

    // 保存key-value的数组。
    // Hashtable同样采用单链表解决冲突,每一个Entry本质上是一个单向链表
    private transient Entry[] table;    

    // Hashtable中键值对的数量
    private transient int count;    

    // 阈值,用于判断是否需要调整Hashtable的容量(threshold = 容量*加载因子)
    private int threshold;    

    // 加载因子
    private float loadFactor;    

    // Hashtable被改变的次数,用于fail-fast机制的实现
    private transient int modCount = 0;    

    // 序列版本号
    private static final long serialVersionUID = 1421746759512286392L;    

    // 指定“容量大小”和“加载因子”的构造函数
    public Hashtable(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal Load: "+loadFactor);    

        if (initialCapacity==0)
            initialCapacity = 1;
        this.loadFactor = loadFactor;
        table = new Entry[initialCapacity];
        threshold = (int)(initialCapacity * loadFactor);
    }    

    // 指定“容量大小”的构造函数
    public Hashtable(int initialCapacity) {
        this(initialCapacity, 0.75f);
    }    

    // 默认构造函数。
    public Hashtable() {
        // 默认构造函数,指定的容量大小是11;加载因子是0.75
        this(11, 0.75f);
    }    

    // 包含“子Map”的构造函数
    public Hashtable(Map<? extends K, ? extends V> t) {
        this(Math.max(2*t.size(), 11), 0.75f);
        // 将“子Map”的全部元素都添加到Hashtable中
        putAll(t);
    }    

    private int hash(Object k) {
        if (useAltHashing) {
            if (k.getClass() == String.class) {
                return sun.misc.Hashing.stringHash32((String) k);
            } else {
                int h = hashSeed ^ k.hashCode();

                // This function ensures that hashCodes that differ only by
                // constant multiples at each bit position have a bounded
                // number of collisions (approximately 8 at default load factor).
                h ^= (h >>> 20) ^ (h >>> 12);
                return h ^ (h >>> 7) ^ (h >>> 4);
             }
        } else  {
            return k.hashCode();
        }
    }

    public synchronized int size() {
        return count;
    }    

    public synchronized boolean isEmpty() {
        return count == 0;
    }    

    // 返回“所有key”的枚举对象
    public synchronized Enumeration<K> keys() {
        return this.<K>getEnumeration(KEYS);
    }    

    // 返回“所有value”的枚举对象
    public synchronized Enumeration<V> elements() {
        return this.<V>getEnumeration(VALUES);
    }    

    // 判断Hashtable是否包含“值(value)”
    public synchronized boolean contains(Object value) {
        //注意,Hashtable中的value不能是null,
        // 若是null的话,抛出异常!
        if (value == null) {
            throw new NullPointerException();
        }    

        // 从后向前遍历table数组中的元素(Entry)
        // 对于每个Entry(单向链表),逐个遍历,判断节点的值是否等于value
        Entry tab[] = table;
        for (int i = tab.length ; i-- > 0 ;) {
            for (Entry<K,V> e = tab[i] ; e != null ; e = e.next) {
                if (e.value.equals(value)) {
                    return true;
                }
            }
        }
        return false;
    }    

    public boolean containsValue(Object value) {
        return contains(value);
    }    

    // 判断Hashtable是否包含key
    public synchronized boolean containsKey(Object key) {
        Entry tab[] = table;
        //计算hash值,直接用key的hashCode代替
        int hash = key.hashCode();
        // 计算在数组中的索引值
        int index = (hash & 0x7FFFFFFF) % tab.length;
        // 找到“key对应的Entry(链表)”,然后在链表中找出“哈希值”和“键值”与key都相等的元素
        for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
                return true;
            }
        }
        return false;
    }    

    // 返回key对应的value,没有的话返回null
    public synchronized V get(Object key) {
        Entry tab[] = table;
        int hash = hash(key);
        // 计算索引值,
        int index = (hash & 0x7FFFFFFF) % tab.length;
        // 找到“key对应的Entry(链表)”,然后在链表中找出“哈希值”和“键值”与key都相等的元素
        for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
                return e.value;
            }
        }
        return null;
    }    

    // 调整Hashtable的长度,将长度变成原来的2倍+1
    protected void rehash() {
        int oldCapacity = table.length;
        Entry[] oldMap = table;    

        //创建新容量大小的Entry数组
        int newCapacity = oldCapacity * 2 + 1;
        Entry[] newMap = new Entry[newCapacity];    

        modCount++;
        threshold = (int)(newCapacity * loadFactor);
        table = newMap;    

        //将“旧的Hashtable”中的元素复制到“新的Hashtable”中
        for (int i = oldCapacity ; i-- > 0 ;) {
            for (Entry<K,V> old = oldMap[i] ; old != null ; ) {
                Entry<K,V> e = old;
                old = old.next;
                //重新计算index
                int index = (e.hash & 0x7FFFFFFF) % newCapacity;
                e.next = newMap[index];
                newMap[index] = e;
            }
        }
    }    

    // 将“key-value”添加到Hashtable中
    public synchronized V put(K key, V value) {
        // Hashtable中不能插入value为null的元素!!!
        if (value == null) {
            throw new NullPointerException();
        }    

        // 若“Hashtable中已存在键为key的键值对”,
        // 则用“新的value”替换“旧的value”
        Entry tab[] = table;
        int hash = hash(key);
        int index = (hash & 0x7FFFFFFF) % tab.length;
        for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
                V old = e.value;
                e.value = value;
                return old;
                }
        }    

        // 若“Hashtable中不存在键为key的键值对”,
        // 将“修改统计数”+1
        modCount++;
        //  若“Hashtable实际容量” > “阈值”(阈值=总的容量 * 加载因子)
        //  则调整Hashtable的大小
        if (count >= threshold) {
            rehash();    

            tab = table;
            index = (hash & 0x7FFFFFFF) % tab.length;
        }    

        //将新的key-value对插入到tab[index]处(即链表的头结点)
        Entry<K,V> e = tab[index];
        tab[index] = new Entry<K,V>(hash, key, value, e);
        count++;
        return null;
    }    

    // 删除Hashtable中键为key的元素
    public synchronized V remove(Object key) {
        Entry tab[] = table;
        int hash = hash(key);
        int index = (hash & 0x7FFFFFFF) % tab.length;    

        //从table[index]链表中找出要删除的节点,并删除该节点。
        //因为是单链表,因此要保留带删节点的前一个节点,才能有效地删除节点
        for (Entry<K,V> e = tab[index], prev = null ; e != null ; prev = e, e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
                modCount++;
                if (prev != null) {
                    prev.next = e.next;
                } else {
                    tab[index] = e.next;
                }
                count--;
                V oldValue = e.value;
                e.value = null;
                return oldValue;
            }
        }
        return null;
    }    

    // 将“Map(t)”的中全部元素逐一添加到Hashtable中
    public synchronized void putAll(Map<? extends K, ? extends V> t) {
        for (Map.Entry<? extends K, ? extends V> e : t.entrySet())
            put(e.getKey(), e.getValue());
    }    

    // 清空Hashtable
    // 将Hashtable的table数组的值全部设为null
    public synchronized void clear() {
        Entry tab[] = table;
        modCount++;
        for (int index = tab.length; --index >= 0; )
            tab[index] = null;
        count = 0;
    }    

    // 克隆一个Hashtable,并以Object的形式返回。
    public synchronized Object clone() {
        try {
            Hashtable<K,V> t = (Hashtable<K,V>) super.clone();
            t.table = new Entry[table.length];
            for (int i = table.length ; i-- > 0 ; ) {
                t.table[i] = (table[i] != null)
                ? (Entry<K,V>) table[i].clone() : null;
            }
            t.keySet = null;
            t.entrySet = null;
            t.values = null;
            t.modCount = 0;
            return t;
        } catch (CloneNotSupportedException e) {
            throw new InternalError();
        }
    }    

    public synchronized String toString() {
        int max = size() - 1;
        if (max == -1)
            return "{}";    

        StringBuilder sb = new StringBuilder();
        Iterator<Map.Entry<K,V>> it = entrySet().iterator();    

        sb.append(‘{‘);
        for (int i = 0; ; i++) {
            Map.Entry<K,V> e = it.next();
            K key = e.getKey();
            V value = e.getValue();
            sb.append(key   == this ? "(this Map)" : key.toString());
            sb.append(‘=‘);
            sb.append(value == this ? "(this Map)" : value.toString());    

            if (i == max)
                return sb.append(‘}‘).toString();
            sb.append(", ");
        }
    }    

    // 获取Hashtable的枚举类对象
    // 若Hashtable的实际大小为0,则返回“空枚举类”对象;
    // 否则,返回正常的Enumerator的对象。
    private <T> Enumeration<T> getEnumeration(int type) {
    if (count == 0) {
        return (Enumeration<T>)emptyEnumerator;
    } else {
        return new Enumerator<T>(type, false);
    }
    }    

    // 获取Hashtable的迭代器
    // 若Hashtable的实际大小为0,则返回“空迭代器”对象;
    // 否则,返回正常的Enumerator的对象。(Enumerator实现了迭代器和枚举两个接口)
    private <T> Iterator<T> getIterator(int type) {
        if (count == 0) {
            return (Iterator<T>) emptyIterator;
        } else {
            return new Enumerator<T>(type, true);
        }
    }    

    // Hashtable的“key的集合”。它是一个Set,没有重复元素
    private transient volatile Set<K> keySet = null;
    // Hashtable的“key-value的集合”。它是一个Set,没有重复元素
    private transient volatile Set<Map.Entry<K,V>> entrySet = null;
    // Hashtable的“key-value的集合”。它是一个Collection,可以有重复元素
    private transient volatile Collection<V> values = null;    

    // 返回一个被synchronizedSet封装后的KeySet对象
    // synchronizedSet封装的目的是对KeySet的所有方法都添加synchronized,实现多线程同步
    public Set<K> keySet() {
        if (keySet == null)
            keySet = Collections.synchronizedSet(new KeySet(), this);
        return keySet;
    }    

    // Hashtable的Key的Set集合。
    // KeySet继承于AbstractSet,所以,KeySet中的元素没有重复的。
    private class KeySet extends AbstractSet<K> {
        public Iterator<K> iterator() {
            return getIterator(KEYS);
        }
        public int size() {
            return count;
        }
        public boolean contains(Object o) {
            return containsKey(o);
        }
        public boolean remove(Object o) {
            return Hashtable.this.remove(o) != null;
        }
        public void clear() {
            Hashtable.this.clear();
        }
    }    

    // 返回一个被synchronizedSet封装后的EntrySet对象
    // synchronizedSet封装的目的是对EntrySet的所有方法都添加synchronized,实现多线程同步
    public Set<Map.Entry<K,V>> entrySet() {
        if (entrySet==null)
            entrySet = Collections.synchronizedSet(new EntrySet(), this);
        return entrySet;
    }    

    // Hashtable的Entry的Set集合。
    // EntrySet继承于AbstractSet,所以,EntrySet中的元素没有重复的。
    private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
        public Iterator<Map.Entry<K,V>> iterator() {
            return getIterator(ENTRIES);
        }    

        public boolean add(Map.Entry<K,V> o) {
            return super.add(o);
        }    

        // 查找EntrySet中是否包含Object(0)
        // 首先,在table中找到o对应的Entry链表
        // 然后,查找Entry链表中是否存在Object
        public boolean contains(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry entry = (Map.Entry)o;
            Object key = entry.getKey();
            Entry[] tab = table;
            int hash = hash(key);
            int index = (hash & 0x7FFFFFFF) % tab.length;    

            for (Entry e = tab[index]; e != null; e = e.next)
                if (e.hash==hash && e.equals(entry))
                    return true;
            return false;
        }    

        // 删除元素Object(0)
        // 首先,在table中找到o对应的Entry链表
        // 然后,删除链表中的元素Object
        public boolean remove(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
            K key = entry.getKey();
            Entry[] tab = table;
            int hash = hash(key);
            int index = (hash & 0x7FFFFFFF) % tab.length;    

            for (Entry<K,V> e = tab[index], prev = null; e != null;
                 prev = e, e = e.next) {
                if (e.hash==hash && e.equals(entry)) {
                    modCount++;
                    if (prev != null)
                        prev.next = e.next;
                    else
                        tab[index] = e.next;    

                    count--;
                    e.value = null;
                    return true;
                }
            }
            return false;
        }    

        public int size() {
            return count;
        }    

        public void clear() {
            Hashtable.this.clear();
        }
    }    

    // 返回一个被synchronizedCollection封装后的ValueCollection对象
    // synchronizedCollection封装的目的是对ValueCollection的所有方法都添加synchronized,实现多线程同步
    public Collection<V> values() {
    if (values==null)
        values = Collections.synchronizedCollection(new ValueCollection(),
                                                        this);
        return values;
    }    

    // Hashtable的value的Collection集合。
    // ValueCollection继承于AbstractCollection,所以,ValueCollection中的元素可以重复的。
    private class ValueCollection extends AbstractCollection<V> {
        public Iterator<V> iterator() {
        return getIterator(VALUES);
        }
        public int size() {
            return count;
        }
        public boolean contains(Object o) {
            return containsValue(o);
        }
        public void clear() {
            Hashtable.this.clear();
        }
    }    

    // 重新equals()函数
    // 若两个Hashtable的所有key-value键值对都相等,则判断它们两个相等
    public synchronized boolean equals(Object o) {
        if (o == this)
            return true;    

        if (!(o instanceof Map))
            return false;
        Map<K,V> t = (Map<K,V>) o;
        if (t.size() != size())
            return false;    

        try {
            // 通过迭代器依次取出当前Hashtable的key-value键值对
            // 并判断该键值对,存在于Hashtable中。
            // 若不存在,则立即返回false;否则,遍历完“当前Hashtable”并返回true。
            Iterator<Map.Entry<K,V>> i = entrySet().iterator();
            while (i.hasNext()) {
                Map.Entry<K,V> e = i.next();
                K key = e.getKey();
                V value = e.getValue();
                if (value == null) {
                    if (!(t.get(key)==null && t.containsKey(key)))
                        return false;
                } else {
                    if (!value.equals(t.get(key)))
                        return false;
                }
            }
        } catch (ClassCastException unused)   {
            return false;
        } catch (NullPointerException unused) {
            return false;
        }    

        return true;
    }    

    // 计算Entry的hashCode
    // 若 Hashtable的实际大小为0 或者 加载因子<0,则返回0。
    // 否则,返回“Hashtable中的每个Entry的key和value的异或值 的总和”。
    public synchronized int hashCode() {
        int h = 0;
        if (count == 0 || loadFactor < 0)
            return h;  // Returns zero    

        loadFactor = -loadFactor;  // Mark hashCode computation in progress
        Entry[] tab = table;
        for (int i = 0; i < tab.length; i++)
            for (Entry e = tab[i]; e != null; e = e.next)
                h += e.key.hashCode() ^ e.value.hashCode();
        loadFactor = -loadFactor;  // Mark hashCode computation complete    

        return h;
    }    

    // java.io.Serializable的写入函数
    // 将Hashtable的“总的容量,实际容量,所有的Entry”都写入到输出流中
    private synchronized void writeObject(java.io.ObjectOutputStream s)
        throws IOException
    {
        // Write out the length, threshold, loadfactor
        s.defaultWriteObject();    

        // Write out length, count of elements and then the key/value objects
        s.writeInt(table.length);
        s.writeInt(count);
        for (int index = table.length-1; index >= 0; index--) {
            Entry entry = table[index];    

            while (entry != null) {
            s.writeObject(entry.key);
            s.writeObject(entry.value);
            entry = entry.next;
            }
        }
    }    

    // java.io.Serializable的读取函数:根据写入方式读出
    // 将Hashtable的“总的容量,实际容量,所有的Entry”依次读出
    private void readObject(java.io.ObjectInputStream s)
         throws IOException, ClassNotFoundException
    {
        // Read in the length, threshold, and loadfactor
        s.defaultReadObject();    

        // Read the original length of the array and number of elements
        int origlength = s.readInt();
        int elements = s.readInt();    

        // Compute new size with a bit of room 5% to grow but
        // no larger than the original size.  Make the length
        // odd if it‘s large enough, this helps distribute the entries.
        // Guard against the length ending up zero, that‘s not valid.
        int length = (int)(elements * loadFactor) + (elements / 20) + 3;
        if (length > elements && (length & 1) == 0)
            length--;
        if (origlength > 0 && length > origlength)
            length = origlength;    

        Entry[] table = new Entry[length];
        count = 0;    

        // Read the number of elements and then all the key/value objects
        for (; elements > 0; elements--) {
            K key = (K)s.readObject();
            V value = (V)s.readObject();
                // synch could be eliminated for performance
                reconstitutionPut(table, key, value);
        }
        this.table = table;
    }    

    private void reconstitutionPut(Entry[] tab, K key, V value)
        throws StreamCorruptedException
    {
        if (value == null) {
            throw new java.io.StreamCorruptedException();
        }
        // Makes sure the key is not already in the hashtable.
        // This should not happen in deserialized version.
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
                throw new java.io.StreamCorruptedException();
            }
        }
        // Creates the new entry.
        Entry<K,V> e = tab[index];
        tab[index] = new Entry<K,V>(hash, key, value, e);
        count++;
    }    

    // Hashtable的Entry节点,它本质上是一个单向链表。
    // 也因此,我们才能推断出Hashtable是由拉链法实现的散列表
    private static class Entry<K,V> implements Map.Entry<K,V> {
        // 哈希值
        int hash;
        K key;
        V value;
        // 指向的下一个Entry,即链表的下一个节点
        Entry<K,V> next;    

        // 构造函数
        protected Entry(int hash, K key, V value, Entry<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }    

        protected Object clone() {
            return new Entry<K,V>(hash, key, value,
                  (next==null ? null : (Entry<K,V>) next.clone()));
        }    

        public K getKey() {
            return key;
        }    

        public V getValue() {
            return value;
        }    

        // 设置value。若value是null,则抛出异常。
        public V setValue(V value) {
            if (value == null)
                throw new NullPointerException();    

            V oldValue = this.value;
            this.value = value;
            return oldValue;
        }    

        // 覆盖equals()方法,判断两个Entry是否相等。
        // 若两个Entry的key和value都相等,则认为它们相等。
        public boolean equals(Object o) {
            if (!(o instanceof Map.Entry))
                return false;
            Map.Entry e = (Map.Entry)o;    

            return (key==null ? e.getKey()==null : key.equals(e.getKey())) &&
               (value==null ? e.getValue()==null : value.equals(e.getValue()));
        }    

        public int hashCode() {
            return hash ^ (value==null ? 0 : value.hashCode());
        }    

        public String toString() {
            return key.toString()+"="+value.toString();
        }
    }    

    private static final int KEYS = 0;
    private static final int VALUES = 1;
    private static final int ENTRIES = 2;    

    // Enumerator的作用是提供了“通过elements()遍历Hashtable的接口” 和 “通过entrySet()遍历Hashtable的接口”。
    private class Enumerator<T> implements Enumeration<T>, Iterator<T> {
        // 指向Hashtable的table
        Entry[] table = Hashtable.this.table;
        // Hashtable的总的大小
        int index = table.length;
        Entry<K,V> entry = null;
        Entry<K,V> lastReturned = null;
        int type;    

        // Enumerator是 “迭代器(Iterator)” 还是 “枚举类(Enumeration)”的标志
        // iterator为true,表示它是迭代器;否则,是枚举类。
        boolean iterator;    

        // 在将Enumerator当作迭代器使用时会用到,用来实现fail-fast机制。
        protected int expectedModCount = modCount;    

        Enumerator(int type, boolean iterator) {
            this.type = type;
            this.iterator = iterator;
        }    

        // 从遍历table的数组的末尾向前查找,直到找到不为null的Entry。
        public boolean hasMoreElements() {
            Entry<K,V> e = entry;
            int i = index;
            Entry[] t = table;
            /* Use locals for faster loop iteration */
            while (e == null && i > 0) {
                e = t[--i];
            }
            entry = e;
            index = i;
            return e != null;
        }    

        // 获取下一个元素
        // 注意:从hasMoreElements() 和nextElement() 可以看出“Hashtable的elements()遍历方式”
        // 首先,从后向前的遍历table数组。table数组的每个节点都是一个单向链表(Entry)。
        // 然后,依次向后遍历单向链表Entry。
        public T nextElement() {
            Entry<K,V> et = entry;
            int i = index;
            Entry[] t = table;
            /* Use locals for faster loop iteration */
            while (et == null && i > 0) {
                et = t[--i];
            }
            entry = et;
            index = i;
            if (et != null) {
                Entry<K,V> e = lastReturned = entry;
                entry = e.next;
                return type == KEYS ? (T)e.key : (type == VALUES ? (T)e.value : (T)e);
            }
            throw new NoSuchElementException("Hashtable Enumerator");
        }    

        // 迭代器Iterator的判断是否存在下一个元素
        // 实际上,它是调用的hasMoreElements()
        public boolean hasNext() {
            return hasMoreElements();
        }    

        // 迭代器获取下一个元素
        // 实际上,它是调用的nextElement()
        public T next() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            return nextElement();
        }    

        // 迭代器的remove()接口。
        // 首先,它在table数组中找出要删除元素所在的Entry,
        // 然后,删除单向链表Entry中的元素。
        public void remove() {
            if (!iterator)
                throw new UnsupportedOperationException();
            if (lastReturned == null)
                throw new IllegalStateException("Hashtable Enumerator");
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();    

            synchronized(Hashtable.this) {
                Entry[] tab = Hashtable.this.table;
                int index = (lastReturned.hash & 0x7FFFFFFF) % tab.length;    

                for (Entry<K,V> e = tab[index], prev = null; e != null;
                     prev = e, e = e.next) {
                    if (e == lastReturned) {
                        modCount++;
                        expectedModCount++;
                        if (prev == null)
                            tab[index] = e.next;
                        else
                            prev.next = e.next;
                        count--;
                        lastReturned = null;
                        return;
                    }
                }
                throw new ConcurrentModificationException();
            }
        }
    }    

    private static Enumeration emptyEnumerator = new EmptyEnumerator();
    private static Iterator emptyIterator = new EmptyIterator();    

    // 空枚举类
    // 当Hashtable的实际大小为0;此时,又要通过Enumeration遍历Hashtable时,返回的是“空枚举类”的对象。
    private static class EmptyEnumerator implements Enumeration<Object> {    

        EmptyEnumerator() {
        }    

        // 空枚举类的hasMoreElements() 始终返回false
        public boolean hasMoreElements() {
            return false;
        }    

        // 空枚举类的nextElement() 抛出异常
        public Object nextElement() {
            throw new NoSuchElementException("Hashtable Enumerator");
        }
    }    

    // 空迭代器
    // 当Hashtable的实际大小为0;此时,又要通过迭代器遍历Hashtable时,返回的是“空迭代器”的对象。
    private static class EmptyIterator implements Iterator<Object> {    

        EmptyIterator() {
        }    

        public boolean hasNext() {
            return false;
        }    

        public Object next() {
            throw new NoSuchElementException("Hashtable Iterator");
        }    

        public void remove() {
            throw new IllegalStateException("Hashtable Iterator");
        }    

    }
}   

Collection

是最基本的集合接口

继承的接口:Iterable

子接口:List、Set、Queue等

遍历Collection中的每一个元素

它支持一个Iterator()方法,该方法返回一个迭代子,该迭代子可逐一访问Collection中每一个元素

Iterator it = collection.iterator(); // 获得一个迭代子
    while(it.hasNext())  
    {
        Object obj = it.next(); // 得到下一个元素
    }

方法:

retainAll(Collection<?extends E>c);  //保留,交运算
addAll(Collection<?extends E>c);       //添加,并运算
removeAll(Collection<?extends E>c);     //移除,减运算

LinkedList

LinkedList是基于双向循环链表实现的,除了可以当作链表来操作外,它还可以当作栈、队列和双端队列来使用。

非线程安全,单线程下使用

LinkedList实现了Serializable接口,因此它支持序列化,能够通过序列化传输,实现了Cloneable接口,能被克隆。

  • 是一个类
  • 实现的接口:List、Collection、Iterable、Serializable、Cloneable、Deque,Queue
  • 子类:没有子类

添加元素方法:

boolean add(E e) 添加到链表末尾

void add(int index, E e) 添加到指定位置

boolean addAll(int index, Collection<? extends E> c)

boolean addAll(Collection<? extends E> c)

package java.util;    

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
    // 链表的表头,表头不包含任何数据。Entry是个链表类数据结构。
    private transient Entry<E> header = new Entry<E>(null, null, null);    

    // LinkedList中元素个数
    private transient int size = 0;    

    // 默认构造函数:创建一个空的链表
    public LinkedList() {
        header.next = header.previous = header;
    }    

    // 包含“集合”的构造函数:创建一个包含“集合”的LinkedList
    public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }    

    // 获取LinkedList的第一个元素
    public E getFirst() {
        if (size==0)
            throw new NoSuchElementException();    

        // 链表的表头header中不包含数据。
        // 这里返回header所指下一个节点所包含的数据。
        return header.next.element;
    }    

    // 获取LinkedList的最后一个元素
    public E getLast()  {
        if (size==0)
            throw new NoSuchElementException();    

        // 由于LinkedList是双向链表;而表头header不包含数据。
        // 因而,这里返回表头header的前一个节点所包含的数据。
        return header.previous.element;
    }    

    // 删除LinkedList的第一个元素
    public E removeFirst() {
        return remove(header.next);
    }    

    // 删除LinkedList的最后一个元素
    public E removeLast() {
        return remove(header.previous);
    }    

    // 将元素添加到LinkedList的起始位置
    public void addFirst(E e) {
        addBefore(e, header.next);
    }    

    // 将元素添加到LinkedList的结束位置
    public void addLast(E e) {
        addBefore(e, header);
    }    

    // 判断LinkedList是否包含元素(o)
    public boolean contains(Object o) {
        return indexOf(o) != -1;
    }    

    // 返回LinkedList的大小
    public int size() {
        return size;
    }    

    // 将元素(E)添加到LinkedList中
    public boolean add(E e) {
        // 将节点(节点数据是e)添加到表头(header)之前。
        // 即,将节点添加到双向链表的末端。
        addBefore(e, header);
        return true;
    }    

    // 从LinkedList中删除元素(o)
    // 从链表开始查找,如存在元素(o)则删除该元素并返回true;
    // 否则,返回false。
    public boolean remove(Object o) {
        if (o==null) {
            // 若o为null的删除情况
            for (Entry<E> e = header.next; e != header; e = e.next) {
                if (e.element==null) {
                    remove(e);
                    return true;
                }
            }
        } else {
            // 若o不为null的删除情况
            for (Entry<E> e = header.next; e != header; e = e.next) {
                if (o.equals(e.element)) {
                    remove(e);
                    return true;
                }
            }
        }
        return false;
    }    

    // 将“集合(c)”添加到LinkedList中。
    // 实际上,是从双向链表的末尾开始,将“集合(c)”添加到双向链表中。
    public boolean addAll(Collection<? extends E> c) {
        return addAll(size, c);
    }    

    // 从双向链表的index开始,将“集合(c)”添加到双向链表中。
    public boolean addAll(int index, Collection<? extends E> c) {
        if (index < 0 || index > size)
            throw new IndexOutOfBoundsException("Index: "+index+
                                                ", Size: "+size);
        Object[] a = c.toArray();
        // 获取集合的长度
        int numNew = a.length;
        if (numNew==0)
            return false;
        modCount++;    

        // 设置“当前要插入节点的后一个节点”
        Entry<E> successor = (index==size ? header : entry(index));
        // 设置“当前要插入节点的前一个节点”
        Entry<E> predecessor = successor.previous;
        // 将集合(c)全部插入双向链表中
        for (int i=0; i<numNew; i++) {
            Entry<E> e = new Entry<E>((E)a[i], successor, predecessor);
            predecessor.next = e;
            predecessor = e;
        }
        successor.previous = predecessor;    

        // 调整LinkedList的实际大小
        size += numNew;
        return true;
    }    

    // 清空双向链表
    public void clear() {
        Entry<E> e = header.next;
        // 从表头开始,逐个向后遍历;对遍历到的节点执行一下操作:
        // (01) 设置前一个节点为null
        // (02) 设置当前节点的内容为null
        // (03) 设置后一个节点为“新的当前节点”
        while (e != header) {
            Entry<E> next = e.next;
            e.next = e.previous = null;
            e.element = null;
            e = next;
        }
        header.next = header.previous = header;
        // 设置大小为0
        size = 0;
        modCount++;
    }    

    // 返回LinkedList指定位置的元素
    public E get(int index) {
        return entry(index).element;
    }    

    // 设置index位置对应的节点的值为element
    public E set(int index, E element) {
        Entry<E> e = entry(index);
        E oldVal = e.element;
        e.element = element;
        return oldVal;
    }    

    // 在index前添加节点,且节点的值为element
    public void add(int index, E element) {
        addBefore(element, (index==size ? header : entry(index)));
    }    

    // 删除index位置的节点
    public E remove(int index) {
        return remove(entry(index));
    }    

    // 获取双向链表中指定位置的节点
    private Entry<E> entry(int index) {
        if (index < 0 || index >= size)
            throw new IndexOutOfBoundsException("Index: "+index+
                                                ", Size: "+size);
        Entry<E> e = header;
        // 获取index处的节点。
        // 若index < 双向链表长度的1/2,则从前先后查找;
        // 否则,从后向前查找。
        if (index < (size >> 1)) {
            for (int i = 0; i <= index; i++)
                e = e.next;
        } else {
            for (int i = size; i > index; i--)
                e = e.previous;
        }
        return e;
    }    

    // 从前向后查找,返回“值为对象(o)的节点对应的索引”
    // 不存在就返回-1
    public int indexOf(Object o) {
        int index = 0;
        if (o==null) {
            for (Entry e = header.next; e != header; e = e.next) {
                if (e.element==null)
                    return index;
                index++;
            }
        } else {
            for (Entry e = header.next; e != header; e = e.next) {
                if (o.equals(e.element))
                    return index;
                index++;
            }
        }
        return -1;
    }    

    // 从后向前查找,返回“值为对象(o)的节点对应的索引”
    // 不存在就返回-1
    public int lastIndexOf(Object o) {
        int index = size;
        if (o==null) {
            for (Entry e = header.previous; e != header; e = e.previous) {
                index--;
                if (e.element==null)
                    return index;
            }
        } else {
            for (Entry e = header.previous; e != header; e = e.previous) {
                index--;
                if (o.equals(e.element))
                    return index;
            }
        }
        return -1;
    }    

    // 返回第一个节点
    // 若LinkedList的大小为0,则返回null
    public E peek() {
        if (size==0)
            return null;
        return getFirst();
    }    

    // 返回第一个节点
    // 若LinkedList的大小为0,则抛出异常
    public E element() {
        return getFirst();
    }    

    // 删除并返回第一个节点
    // 若LinkedList的大小为0,则返回null
    public E poll() {
        if (size==0)
            return null;
        return removeFirst();
    }    

    // 将e添加双向链表末尾
    public boolean offer(E e) {
        return add(e);
    }    

    // 将e添加双向链表开头
    public boolean offerFirst(E e) {
        addFirst(e);
        return true;
    }    

    // 将e添加双向链表末尾
    public boolean offerLast(E e) {
        addLast(e);
        return true;
    }    

    // 返回第一个节点
    // 若LinkedList的大小为0,则返回null
    public E peekFirst() {
        if (size==0)
            return null;
        return getFirst();
    }    

    // 返回最后一个节点
    // 若LinkedList的大小为0,则返回null
    public E peekLast() {
        if (size==0)
            return null;
        return getLast();
    }    

    // 删除并返回第一个节点
    // 若LinkedList的大小为0,则返回null
    public E pollFirst() {
        if (size==0)
            return null;
        return removeFirst();
    }    

    // 删除并返回最后一个节点
    // 若LinkedList的大小为0,则返回null
    public E pollLast() {
        if (size==0)
            return null;
        return removeLast();
    }    

    // 将e插入到双向链表开头
    public void push(E e) {
        addFirst(e);
    }    

    // 删除并返回第一个节点
    public E pop() {
        return removeFirst();
    }    

    // 从LinkedList开始向后查找,删除第一个值为元素(o)的节点
    // 从链表开始查找,如存在节点的值为元素(o)的节点,则删除该节点
    public boolean removeFirstOccurrence(Object o) {
        return remove(o);
    }    

    // 从LinkedList末尾向前查找,删除第一个值为元素(o)的节点
    // 从链表开始查找,如存在节点的值为元素(o)的节点,则删除该节点
    public boolean removeLastOccurrence(Object o) {
        if (o==null) {
            for (Entry<E> e = header.previous; e != header; e = e.previous) {
                if (e.element==null) {
                    remove(e);
                    return true;
                }
            }
        } else {
            for (Entry<E> e = header.previous; e != header; e = e.previous) {
                if (o.equals(e.element)) {
                    remove(e);
                    return true;
                }
            }
        }
        return false;
    }    

    // 返回“index到末尾的全部节点”对应的ListIterator对象(List迭代器)
    public ListIterator<E> listIterator(int index) {
        return new ListItr(index);
    }    

    // List迭代器
    private class ListItr implements ListIterator<E> {
        // 上一次返回的节点
        private Entry<E> lastReturned = header;
        // 下一个节点
        private Entry<E> next;
        // 下一个节点对应的索引值
        private int nextIndex;
        // 期望的改变计数。用来实现fail-fast机制。
        private int expectedModCount = modCount;    

        // 构造函数。
        // 从index位置开始进行迭代
        ListItr(int index) {
            // index的有效性处理
            if (index < 0 || index > size)
                throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+size);
            // 若 “index 小于 ‘双向链表长度的一半’”,则从第一个元素开始往后查找;
            // 否则,从最后一个元素往前查找。
            if (index < (size >> 1)) {
                next = header.next;
                for (nextIndex=0; nextIndex<index; nextIndex++)
                    next = next.next;
            } else {
                next = header;
                for (nextIndex=size; nextIndex>index; nextIndex--)
                    next = next.previous;
            }
        }    

        // 是否存在下一个元素
        public boolean hasNext() {
            // 通过元素索引是否等于“双向链表大小”来判断是否达到最后。
            return nextIndex != size;
        }    

        // 获取下一个元素
        public E next() {
            checkForComodification();
            if (nextIndex == size)
                throw new NoSuchElementException();    

            lastReturned = next;
            // next指向链表的下一个元素
            next = next.next;
            nextIndex++;
            return lastReturned.element;
        }    

        // 是否存在上一个元素
        public boolean hasPrevious() {
            // 通过元素索引是否等于0,来判断是否达到开头。
            return nextIndex != 0;
        }    

        // 获取上一个元素
        public E previous() {
            if (nextIndex == 0)
            throw new NoSuchElementException();    

            // next指向链表的上一个元素
            lastReturned = next = next.previous;
            nextIndex--;
            checkForComodification();
            return lastReturned.element;
        }    

        // 获取下一个元素的索引
        public int nextIndex() {
            return nextIndex;
        }    

        // 获取上一个元素的索引
        public int previousIndex() {
            return nextIndex-1;
        }    

        // 删除当前元素。
        // 删除双向链表中的当前节点
        public void remove() {
            checkForComodification();
            Entry<E> lastNext = lastReturned.next;
            try {
                LinkedList.this.remove(lastReturned);
            } catch (NoSuchElementException e) {
                throw new IllegalStateException();
            }
            if (next==lastReturned)
                next = lastNext;
            else
                nextIndex--;
            lastReturned = header;
            expectedModCount++;
        }    

        // 设置当前节点为e
        public void set(E e) {
            if (lastReturned == header)
                throw new IllegalStateException();
            checkForComodification();
            lastReturned.element = e;
        }    

        // 将e添加到当前节点的前面
        public void add(E e) {
            checkForComodification();
            lastReturned = header;
            addBefore(e, next);
            nextIndex++;
            expectedModCount++;
        }    

        // 判断 “modCount和expectedModCount是否相等”,依次来实现fail-fast机制。
        final void checkForComodification() {
            if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
        }
    }    

    // 双向链表的节点所对应的数据结构。
    // 包含3部分:上一节点,下一节点,当前节点值。
    private static class Entry<E> {
        // 当前节点所包含的值
        E element;
        // 下一个节点
        Entry<E> next;
        // 上一个节点
        Entry<E> previous;    

        /**
         * 链表节点的构造函数。
         * 参数说明:
         *   element  —— 节点所包含的数据
         *   next      —— 下一个节点
         *   previous —— 上一个节点
         */
        Entry(E element, Entry<E> next, Entry<E> previous) {
            this.element = element;
            this.next = next;
            this.previous = previous;
        }
    }    

    // 将节点(节点数据是e)添加到entry节点之前。
    private Entry<E> addBefore(E e, Entry<E> entry) {
        // 新建节点newEntry,将newEntry插入到节点e之前;并且设置newEntry的数据是e
        Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);
        newEntry.previous.next = newEntry;
        newEntry.next.previous = newEntry;
        // 修改LinkedList大小
        size++;
        // 修改LinkedList的修改统计数:用来实现fail-fast机制。
        modCount++;
        return newEntry;
    }    

    // 将节点从链表中删除
    private E remove(Entry<E> e) {
        if (e == header)
            throw new NoSuchElementException();    

        E result = e.element;
        e.previous.next = e.next;
        e.next.previous = e.previous;
        e.next = e.previous = null;
        e.element = null;
        size--;
        modCount++;
        return result;
    }    

    // 反向迭代器
    public Iterator<E> descendingIterator() {
        return new DescendingIterator();
    }    

    // 反向迭代器实现类。
    private class DescendingIterator implements Iterator {
        final ListItr itr = new ListItr(size());
        // 反向迭代器是否下一个元素。
        // 实际上是判断双向链表的当前节点是否达到开头
        public boolean hasNext() {
            return itr.hasPrevious();
        }
        // 反向迭代器获取下一个元素。
        // 实际上是获取双向链表的前一个节点
        public E next() {
            return itr.previous();
        }
        // 删除当前节点
        public void remove() {
            itr.remove();
        }
    }    

    // 返回LinkedList的Object[]数组
    public Object[] toArray() {
    // 新建Object[]数组
    Object[] result = new Object[size];
        int i = 0;
        // 将链表中所有节点的数据都添加到Object[]数组中
        for (Entry<E> e = header.next; e != header; e = e.next)
            result[i++] = e.element;
    return result;
    }    

    // 返回LinkedList的模板数组。所谓模板数组,即可以将T设为任意的数据类型
    public <T> T[] toArray(T[] a) {
        // 若数组a的大小 < LinkedList的元素个数(意味着数组a不能容纳LinkedList中全部元素)
        // 则新建一个T[]数组,T[]的大小为LinkedList大小,并将该T[]赋值给a。
        if (a.length < size)
            a = (T[])java.lang.reflect.Array.newInstance(
                                a.getClass().getComponentType(), size);
        // 将链表中所有节点的数据都添加到数组a中
        int i = 0;
        Object[] result = a;
        for (Entry<E> e = header.next; e != header; e = e.next)
            result[i++] = e.element;    

        if (a.length > size)
            a[size] = null;    

        return a;
    }    

    // 克隆函数。返回LinkedList的克隆对象。
    public Object clone() {
        LinkedList<E> clone = null;
        // 克隆一个LinkedList克隆对象
        try {
            clone = (LinkedList<E>) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new InternalError();
        }    

        // 新建LinkedList表头节点
        clone.header = new Entry<E>(null, null, null);
        clone.header.next = clone.header.previous = clone.header;
        clone.size = 0;
        clone.modCount = 0;    

        // 将链表中所有节点的数据都添加到克隆对象中
        for (Entry<E> e = header.next; e != header; e = e.next)
            clone.add(e.element);    

        return clone;
    }    

    // java.io.Serializable的写入函数
    // 将LinkedList的“容量,所有的元素值”都写入到输出流中
    private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException {
        // Write out any hidden serialization magic
        s.defaultWriteObject();    

        // 写入“容量”
        s.writeInt(size);    

        // 将链表中所有节点的数据都写入到输出流中
        for (Entry e = header.next; e != header; e = e.next)
            s.writeObject(e.element);
    }    

    // java.io.Serializable的读取函数:根据写入方式反向读出
    // 先将LinkedList的“容量”读出,然后将“所有的元素值”读出
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        // Read in any hidden serialization magic
        s.defaultReadObject();    

        // 从输入流中读取“容量”
        int size = s.readInt();    

        // 新建链表表头节点
        header = new Entry<E>(null, null, null);
        header.next = header.previous = header;    

        // 从输入流中将“所有的元素值”并逐个添加到链表中
        for (int i=0; i<size; i++)
            addBefore((E)s.readObject(), header);
    }
}   

原文地址:https://www.cnblogs.com/daminzhou/p/8406460.html

时间: 2024-10-13 11:55:12

常用数据结构底层实现及源码的相关文章

开源一个常用的小软件的源码——系统数据库服务管理软件

郝喜路  2014年7月27日22:28:34 GitHub地址:https://github.com/haoxilu/ServiceManager    希望编程爱好者 更改添加...   开发环境:Visual Studio 2012   .Net Framework 4.0 大家在软件开发过程中,是离不开 数据库的,不管你用什么数据库,都会在系统服务上注册一个,当你安装了太多的数据库,是否有感到极大的拖掉了开机时间,影响了计算机的性能.(仅限windows系统).这时有的朋友可能会想到手动

【数据结构】2.java源码关于LinkedList

关于LinkedList的源码关注点 1.从底层数据结构,扩容策略2.LinkedList的增删改查3.特殊处理重点关注4.遍历的速度,随机访问和iterator访问效率对比 1.从底层数据结构,扩容策略 构造函数不做任何操作,只要再add的时候进行数据初始化操作,以操作推动逻辑,而且linkedlist是一个双向链表,所以可以向前向后双向遍历由于构造函数并没有任何操作,其实这里我们可以先看新增操作,并且因为用的是链表所以无法随机访问,这里随机读取就会比较慢 ? 底层结构就是size,首节点,尾

《Redis设计与实现》[第一部分]数据结构与对象-C源码阅读(一)

一.简单动态字符串SDS 关键字:空间预分配,惰性空间释放,二进制安全 C字符串不易更改,所以Redis中把C字符串用在一些无须对字符串值进行修改的地方,作为字符串字面量(String literal),比如打印日志: redisLog(REDIS_WARING, "Redis is now ready to exit, bye bye-"); 在Redis数据库中,包含字符串的键值对在底层都是由SDS实现的. SDS还被用作缓冲区(buffer):AOF模块中的AOF缓冲区,以及客户

常用sql语句,SSC源码开发堪称经典

1.查询"001"课程比"002"课程成绩高的所有学生的学号; select a.S# from (select S#,score from SC where C#='001') a,(select S#,score from SC where C#='002') b where a.score>b.score and a.S#=b.S#; 2.查询平均成绩大于60分的同学的学号和平均成绩; select S#,avg(score) from SC group

linux常用命令5 yum、源码安装

一.软件安装 rpm rpm -ivh zziplib-0.13.62-5.el7.x86_64.rpm //安装zziplib-0.13.62-5.el7.x86_64.rpm rpm -qf `which cd` //查看cd的包名,这里使用反引号,rpm会取反引号中命令的结果作为参数, rpm包格式,包名.版本号.发布版本号.平台 rpm -ivh rpm包文件 //安装 rpm -Uvh rpm包文件 //升级 rpm -e 包名 //卸载 rpm -qa //查询安装的包 rpm -q

firefox 自写底层扩展,源码简介

还记得10年的时候,那时候开始喜欢上了js,经常逛MDN 一开始写些简单的油猴脚本,慢慢的接触了扩展开发,发现用自己的js知识 加上firefox的插件API,可以完成好多功能. 看了很多插件的源代码,集成很多插件功能,代码也是重构了好几个版本(基于FF功能,Components.utils.import封装了require模块加载,sqlite数据库操作,http拦截, 定时任务,Prefs操作等) 也发现FF插件其实很不安全(可以拦截http请求进行修改,进行中间人攻击) 不知不觉就写了2年

java常用关键词关键字,方法源码解析

transient volatile native final Integer String Class &&Object newInstance Class.forName,ClassLoader.loadClass ClassLoader .getResources(), ClassLoader.getSystemResources() ClassLoader .getResources(), ClassLoader.getSystemResources() public Enumer

死磕 Java 系列(一)&mdash;&mdash; 常用类(1) String 源码解析

写在前面 这是博主新开的一个 java 学习系列,听名字就可以看出来,在这一些系列中,我们学习的知识点不再是蜻蜓点水,而是深入底层,深入源码.由此,学习过程中我们要带着一股钻劲儿,对我们不懂的知识充满质疑,力求把我们学过的知识点都搞清楚,想明白. 一.引言 在 java 的世界里,存在一种特殊的类,它们的创建方式极为特别,不需要用到 new XXX(当然也可以用这种方式创建), 但是却大量出现在我们的代码中,那就是 String 类.作为日常中使用频率最高的类,它是那么普通,普通到我们从来都不会

Java集合:HashMap源码剖析

一.HashMap概述二.HashMap的数据结构三.HashMap源码分析     1.关键属性     2.构造方法     3.存储数据     4.调整大小 5.数据读取                       6.HashMap的性能参数                      7.Fail-Fast机制 一.HashMap概述 HashMap基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.(除了不同步和允许使用 null