集合框架源码分析三(实现类篇ArrayList,LinkedList,HashMap)

一。ArrayList,可自动扩充容量的动态数组
Java代码   收藏代码
  1. public class ArrayList<E> extends AbstractList<E> implements List<E>,  
  2.         RandomAccess, Cloneable, java.io.Serializable {  
  3.     private static final long serialVersionUID = 8683452581122892189L;  
  4.   
  5.     /** 
  6.      *  
  7.      * 所有ArrayList的元素都存储在此对象数组当中 
  8.      * ArrayList的容量就是此数组的长度 
  9.      */  
  10.     private transient Object[] elementData;  
  11.   
  12.     /** 
  13.      * 实际拥有的元素的数量 
  14.      *  
  15.      * @serial 
  16.      */  
  17.     private int size;  
  18.   
  19.     /** 
  20.      * 构造方法一,指定elementData数组初始长度 
  21.      */  
  22.     public ArrayList(int initialCapacity) {  
  23.         super();  
  24.         if (initialCapacity < 0//小于0则抛出IllegalArgumentException  
  25.             throw new IllegalArgumentException("Illegal Capacity: "  
  26.                     + initialCapacity);  
  27.         this.elementData = new Object[initialCapacity];  
  28.     }  
  29.   
  30.     /** 
  31.      * 构造方法二,默认elementData数组初始长度为10 
  32.      */  
  33.     public ArrayList() {  
  34.         this(10);  
  35.     }  
  36.   
  37.     /** 
  38.      * 构造方法三,构造一个包含指定 collection 的元素的List 
  39.      */  
  40.     public ArrayList(Collection<? extends E> c) {  
  41.         elementData = c.toArray();      //toArray方法由AbstractCollection实现,返回一个对象数组  
  42.         size = elementData.length;      //元素的顺序是由迭代器迭代顺序决定的,详情见toArray方法实现  
  43.         // c.toArray might (incorrectly) not return Object[] (see 6260652)  
  44.         if (elementData.getClass() != Object[].class)   //如果返回的不是一个数组对象  
  45.             elementData = Arrays.copyOf(elementData, size, Object[].class);  
  46.     }  
  47.   
  48.     /** 
  49.      * 修剪ArrayList的容量为实际size长度 
  50.      */  
  51.     public void trimToSize() {  
  52.         modCount++;         //此方法改变了数组结构,需要检测是否同步  
  53.         int oldCapacity = elementData.length;  
  54.         if (size < oldCapacity) {  
  55.             elementData = Arrays.copyOf(elementData, size);  
  56.         }  
  57.     }  
  58.   
  59.     /** 
  60.      *  
  61.      * 扩充数组容量,并指定其最小的容量,即至少容量大小为minCapacity 
  62.      */  
  63.     public void ensureCapacity(int minCapacity) {  
  64.         modCount++;  
  65.         int oldCapacity = elementData.length;  
  66.         if (minCapacity > oldCapacity) { //指定最小容量比原来容量大才扩充  
  67.             Object oldData[] = elementData;  
  68.             int newCapacity = (oldCapacity * 3) / 2 + 1;    //扩充原容量的1.5倍加1  
  69.             if (newCapacity < minCapacity)   //扩充后还是小于要求的最小容量,则扩充容量为最小容量  
  70.                 newCapacity = minCapacity;  
  71.             elementData = Arrays.copyOf(elementData, newCapacity);  
  72.         }  
  73.     }  
  74.   
  75.     /** 
  76.      * 返回List中的元素个数 
  77.      */  
  78.     public int size() {  
  79.         return size;  
  80.     }  
  81.   
  82.     /** 
  83.      * List是否不含元素 
  84.      */  
  85.     public boolean isEmpty() {  
  86.         return size == 0;  
  87.     }  
  88.   
  89.     /** 
  90.      * 查看o是否包含在ArrayList中,内部调用了indexOf方法实现 
  91.      */  
  92.     public boolean contains(Object o) {  
  93.         return indexOf(o) >= 0;  
  94.     }  
  95.   
  96.     /** 
  97.      * 父类AbstractList的indexOf方法使用的是list迭代器遍历元素 
  98.      * 这里重写了indexOf方法直接遍历数组即可 
  99.      * 返回指定元素第一次在数组中出现的索引 
  100.      * 如果找不到此元素则返回-1 
  101.      */  
  102.     public int indexOf(Object o) {  
  103.         if (o == null) {  
  104.             for (int i = 0; i < size; i++)  
  105.                 if (elementData[i] == null)  
  106.                     return i;  
  107.         } else {  
  108.             for (int i = 0; i < size; i++)  
  109.                 if (o.equals(elementData[i]))  
  110.                     return i;  
  111.         }  
  112.         return -1;  
  113.     }  
  114.   
  115.     /** 
  116.      * 基本同上 
  117.      */  
  118.     public int lastIndexOf(Object o) {  
  119.         if (o == null) {  
  120.             for (int i = size - 1; i >= 0; i--)  
  121.                 if (elementData[i] == null)  
  122.                     return i;  
  123.         } else {  
  124.             for (int i = size - 1; i >= 0; i--)  
  125.                 if (o.equals(elementData[i]))  
  126.                     return i;  
  127.         }  
  128.         return -1;  
  129.     }  
  130.   
  131.     /** 
  132.      *  
  133.      * 返回ArrayList的浅拷贝实例对象,包含所有元素 
  134.      */  
  135.     public Object clone() {  
  136.         try {  
  137.             ArrayList<E> v = (ArrayList<E>) super.clone();  
  138.             v.elementData = Arrays.copyOf(elementData, size);  
  139.             v.modCount = 0;  
  140.             return v;  
  141.         } catch (CloneNotSupportedException e) {    //如果未实现Cloneable则会抛出CloneNotSupportedException  
  142.             throw new InternalError();  
  143.         }  
  144.     }  
  145.   
  146.     /** 
  147.      *  
  148.      * 返回的对象数组是安全的,因为它是一个全新的对象 
  149.      * 操作返回的数组并不会影响到ArrayList对象 
  150.      * 
  151.      */  
  152.     public Object[] toArray() {  
  153.         return Arrays.copyOf(elementData, size);  
  154.     }  
  155.   
  156.     /** 
  157.      * 返回一个指定类型的包含List所有元素的数组 
  158.      */  
  159.     public <T> T[] toArray(T[] a) {  
  160.         if (a.length < size) //如果a的长度小于List元素个数  
  161.             return (T[]) Arrays.copyOf(elementData, size, a.getClass());    //以指定类型返回一个新数组,长度为size  
  162.         System.arraycopy(elementData, 0, a, 0, size);   //否则把elementData中元素复制到a  
  163.         if (a.length > size) //如果a的长度大于size则在最后位置加一个null元素,等于的话就不用加了  
  164.             a[size] = null;     //这对了解它的实际长度很有效  
  165.         return a;  
  166.     }  
  167.   
  168.     // Positional Access Operations  
  169.   
  170.     public E get(int index) {  
  171.         RangeCheck(index);  //检查是否越界  
  172.   
  173.         return (E) elementData[index];  //直接返回数组某位置的元素即可  
  174.     }  
  175.   
  176.     /** 
  177.      * 对数组指定所有的值进行替换,并返回上一个值 
  178.      */  
  179.     public E set(int index, E element) {  
  180.         RangeCheck(index);  //检查是否越界  
  181.   
  182.         E oldValue = (E) elementData[index];    //so easy  
  183.         elementData[index] = element;  
  184.         return oldValue;  
  185.     }  
  186.   
  187.     /** 
  188.      * 在数组size位置添加一个元素 
  189.      *  
  190.      */  
  191.     public boolean add(E e) {  
  192.         ensureCapacity(size + 1); // modCount++,并检查是否需要扩充容量  
  193.         elementData[size++] = e;    //size++  
  194.         return true;  
  195.     }  
  196.   
  197.     /** 
  198.      *  
  199.      * 在指定位置添加一个元素,当前在此位置的元素以及其后面的元素都要向后移动一个位置 
  200.      * 此方法的效率较低 
  201.      * 
  202.      */  
  203.     public void add(int index, E element) {  
  204.         if (index > size || index < 0)    //检查是否越界  
  205.             throw new IndexOutOfBoundsException("Index: " + index + ", Size: "  
  206.                     + size);  
  207.   
  208.         ensureCapacity(size + 1); // Increments modCount!!  
  209.         System.arraycopy(elementData, index, elementData, index + 1, size  
  210.                 - index);   //把原来index位置的元素,复制到index+1的位置,后面的size-index-1长度的元素依次复制  
  211.         elementData[index] = element;   //空出的index位置的元素设为element  
  212.         size++;  
  213.     }  
  214.   
  215.     /** 
  216.      *  
  217.      * 移除指定位置的元素,其后面的元素都要向左移动一个位置 
  218.      * 此方法的效率较低 
  219.      */  
  220.     public E remove(int index) {  
  221.         RangeCheck(index);  
  222.   
  223.         modCount++;     //modCount是为了检测是否发生了并发操作,详细见AbstractList类  
  224.         E oldValue = (E) elementData[index];  
  225.   
  226.         int numMoved = size - index - 1;    //与add相比少移一个元素  
  227.         if (numMoved > 0)    //是否移除的是最后一个元素  
  228.             System.arraycopy(elementData, index + 1, elementData, index,  
  229.                     numMoved);  //index位置的元素被移除了,原来index+1位置的元素复制到index位置,随后的元素依次复制  
  230.         elementData[--size] = null// Let gc do its work,size位置的元素空出来了  
  231.   
  232.         return oldValue;  
  233.     }  
  234.   
  235.     /** 
  236.      *  
  237.      * 如果o在List中存在,移除第一次出现在List中的o元素 
  238.      * 如果o在List中不存在,不做任何操作 
  239.      * 
  240.      */  
  241.     public boolean remove(Object o) {  
  242.         if (o == null) {  
  243.             for (int index = 0; index < size; index++)   //直接遍历数组  
  244.                 if (elementData[index] == null) {  
  245.                     fastRemove(index);      //快速移除此元素  
  246.                     return true;  
  247.                 }  
  248.         } else {  
  249.             for (int index = 0; index < size; index++)  
  250.                 if (o.equals(elementData[index])) {  
  251.                     fastRemove(index);  
  252.                     return true;  
  253.                 }  
  254.         }  
  255.         return false;  
  256.     }  
  257.   
  258.     /* 
  259.      *  
  260.      * 与remove(int index)方法差不多, 
  261.      * 不过不用检测是否越界与返回原来的index位置的值 
  262.      */  
  263.     private void fastRemove(int index) {  
  264.         modCount++;  
  265.         int numMoved = size - index - 1;  
  266.         if (numMoved > 0)  
  267.             System.arraycopy(elementData, index + 1, elementData, index,  
  268.                     numMoved);   
  269.         elementData[--size] = null// Let gc do its work  
  270.     }  
  271.   
  272.     /** 
  273.      * 移除所有元素,即把所有元素设为null,size=0 
  274.      */  
  275.     public void clear() {  
  276.         modCount++;  
  277.   
  278.         // Let gc do its work  
  279.         for (int i = 0; i < size; i++)  
  280.             elementData[i] = null;  
  281.   
  282.         size = 0;  
  283.     }  
  284.   
  285.     /** 
  286.      * 把a中所有元素添加到数组尾部 
  287.      */  
  288.     public boolean addAll(Collection<? extends E> c) {  
  289.         Object[] a = c.toArray();  
  290.         int numNew = a.length;  
  291.         ensureCapacity(size + numNew); // Increments modCount  
  292.         System.arraycopy(a, 0, elementData, size, numNew); //从size位置开始复制a  
  293.         size += numNew;     //size增加  
  294.         return numNew != 0;  
  295.     }  
  296.   
  297.     /** 
  298.      *  
  299.      * 在指定位置开始添加指定集合c中的所有元素 
  300.      * 当前位置及其随后位置的元素后移 
  301.      */  
  302.     public boolean addAll(int index, Collection<? extends E> c) {  
  303.         if (index > size || index < 0)    //检测是否越界  
  304.             throw new IndexOutOfBoundsException("Index: " + index + ", Size: "  
  305.                     + size);  
  306.   
  307.         Object[] a = c.toArray();  
  308.         int numNew = a.length;  
  309.         ensureCapacity(size + numNew); // Increments modCount  
  310.   
  311.         int numMoved = size - index;    //移动元素数量  
  312.         if (numMoved > 0)  
  313.             System.arraycopy(elementData, index, elementData, index + numNew,  
  314.                     numMoved);  //把原来index位置的元素,复制到index+numNew的位置,后面的size-index-1长度的元素依次复制  
  315.   
  316.         System.arraycopy(a, 0, elementData, index, numNew); //空出来的位置填充c  
  317.         size += numNew;  
  318.         return numNew != 0;  
  319.     }  
  320.   
  321.     /** 
  322.      *  
  323.      * 移除所有从fromIndex(包含)到toIndex(不包含)范围内的元素, 
  324.      * 左移随后的元素.如果toIndex=fromIndex,此操作无影响 
  325.      * 
  326.      */  
  327.     protected void removeRange(int fromIndex, int toIndex) {  
  328.         modCount++;  
  329.         int numMoved = size - toIndex;  
  330.         System.arraycopy(elementData, toIndex, elementData, fromIndex,  
  331.                         numMoved);  //把toIndex位置的元素复制到fromIndex,随后的元素依次复制,总共复制numMoved个元素  
  332.   
  333.         // Let gc do its work  
  334.         int newSize = size - (toIndex - fromIndex);   
  335.         while (size != newSize) //这里是为了让gc工作,不直接把size设为newSize  
  336.             elementData[--size] = null;  
  337.     }  
  338.   
  339.     /** 
  340.      *  
  341.      * 这里并没有检测index小于0的情况 
  342.      * 它总是由数组自己检测,抛出的异常也不同,为ArrayIndexOutOfBoundsException 
  343.      */  
  344.     private void RangeCheck(int index) {  
  345.         if (index >= size)  
  346.             throw new IndexOutOfBoundsException("Index: " + index + ", Size: "  
  347.                     + size);  
  348.     }  
  349.   
  350.     /** 
  351.      * 序列化ArrayList,保存ArrayList实例状态 
  352.      * 保存的是数组长度,及其所有元素 
  353.      * 
  354.      */  
  355.     private void writeObject(java.io.ObjectOutputStream s)  
  356.             throws java.io.IOException {  
  357.         // Write out element count, and any hidden stuff  
  358.         int expectedModCount = modCount;  
  359.         s.defaultWriteObject();  
  360.   
  361.         // 写入数组长度  
  362.         s.writeInt(elementData.length);  
  363.   
  364.         // 按顺序写入所有元素  
  365.         for (int i = 0; i < size; i++)  
  366.             s.writeObject(elementData[i]);  
  367.   
  368.         if (modCount != expectedModCount) { //检测到了并发操作  
  369.             throw new ConcurrentModificationException();  
  370.         }  
  371.   
  372.     }  
  373.   
  374.     /** 
  375.      * Reconstitute the <tt>ArrayList</tt> instance from a stream (that is, 
  376.      * deserialize it). 
  377.      */  
  378.     private void readObject(java.io.ObjectInputStream s)  
  379.             throws java.io.IOException, ClassNotFoundException {  
  380.         // Read in size, and any hidden stuff  
  381.         s.defaultReadObject();  
  382.   
  383.         // 读出数组长度  
  384.         int arrayLength = s.readInt();  
  385.         Object[] a = elementData = new Object[arrayLength]; //保存  
  386.   
  387.         // 依次读出所有元素  
  388.         for (int i = 0; i < size; i++)  
  389.             a[i] = s.readObject();  
  390.     }  
  391. }  



二。LikedList(双向循环链表)
Java代码   收藏代码
  1. public class LinkedList<E> extends AbstractSequentialList<E> implements  
  2.         List<E>, Deque<E>, Cloneable, java.io.Serializable {  
  3.     //在第一个节点之前附设的一个节点称为头结点,有元素添加会重设值  
  4.     //此变量在序列化时不保存  
  5.     private transient Entry<E> header = new Entry<E>(nullnullnull);   
  6.     private transient int size = 0;     //List存储的Entry对象个数  
  7.   
  8.     /** 
  9.      * 构造方法一,空链表 
  10.      */  
  11.     public LinkedList() {  
  12.         header.next = header.previous = header;  //只有一个头结点的链表  
  13.     }  
  14.   
  15.     /** 
  16.      * 构造方法二,构造含有指定集合c中所有元素的链表 
  17.      * 具体见addAll方法 
  18.      */  
  19.     public LinkedList(Collection<? extends E> c) {  
  20.         this();  
  21.         addAll(c);  
  22.     }  
  23.   
  24.     /** 
  25.      * 获取第一个元素的值,即头结点的下一个元素的数据部分 
  26.      */  
  27.     public E getFirst() {  
  28.         if (size == 0)  
  29.             throw new NoSuchElementException();  
  30.   
  31.         return header.next.element;  
  32.     }  
  33.   
  34.     /** 
  35.      * 双向循环链表,你懂得 
  36.      */  
  37.     public E getLast() {  
  38.         if (size == 0)  
  39.             throw new NoSuchElementException();  
  40.   
  41.         return header.previous.element;  
  42.     }  
  43.   
  44.     /** 
  45.      * 移除第一个元素,具体见remove()方法 
  46.      */  
  47.     public E removeFirst() {  
  48.         return remove(header.next);  
  49.     }  
  50.   
  51.     /** 
  52.      * 移除最后一个元素 
  53.      */  
  54.     public E removeLast() {  
  55.         return remove(header.previous);  
  56.     }  
  57.   
  58.     /** 
  59.      *  
  60.      * 在链表开始位置添加一个元素 
  61.      * 详情见addBefore() 
  62.      */  
  63.     public void addFirst(E e) {  
  64.         addBefore(e, header.next);  
  65.     }  
  66.   
  67.     /** 
  68.      * 在链表最后位置添加一个元素 
  69.      * 详情见addBefore() 
  70.      */  
  71.     public void addLast(E e) {  
  72.         addBefore(e, header);  
  73.     }  
  74.   
  75.     /** 
  76.      * 查看链表是否包含元素o 
  77.      * 详细见indexOf()方法 
  78.      */  
  79.     public boolean contains(Object o) {  
  80.         return indexOf(o) != -1;  
  81.     }  
  82.   
  83.     /** 
  84.      * 链表所含元素的数量 
  85.      */  
  86.     public int size() {  
  87.         return size;  
  88.     }  
  89.   
  90.     /** 
  91.      * 跟addLast()方法类似,添加成功返回true 
  92.      */  
  93.     public boolean add(E e) {  
  94.         addBefore(e, header);  
  95.         return true;  
  96.     }  
  97.   
  98.     /** 
  99.      * 假如链表中含有一个或多个o对象,移除第一次出现的o 
  100.      * 如果找不到o返回false 
  101.      */  
  102.     public boolean remove(Object o) {  
  103.         if (o == null) {  
  104.             for (Entry<E> e = header.next; e != header; e = e.next) { //从第一个元素开始遍历,每一个Entry对象都包含它下一个元素的信息  
  105.                 if (e.element == null) {  
  106.                     remove(e);  
  107.                     return true;  
  108.                 }  
  109.             }  
  110.         } else {  
  111.             for (Entry<E> e = header.next; e != header; e = e.next) {  
  112.                 if (o.equals(e.element)) {  
  113.                     remove(e);  
  114.                     return true;  
  115.                 }  
  116.             }  
  117.         }  
  118.         return false;  
  119.     }  
  120.   
  121.     /** 
  122.      *  
  123.      * 把c中所有元素按顺序添加到链表尾部 
  124.      */  
  125.     public boolean addAll(Collection<? extends E> c) {  
  126.         return addAll(size, c);  
  127.     }  
  128.   
  129.     /** 
  130.      *  
  131.      * 在指定位置按顺序添加c中所有元素带List中 
  132.      *  
  133.      */  
  134.     public boolean addAll(int index, Collection<? extends E> c) {  
  135.         if (index < 0 || index > size)    //检查是否越界,=size表示添加到最后  
  136.             throw new IndexOutOfBoundsException("Index: " + index + ", Size: "  
  137.                     + size);  
  138.         Object[] a = c.toArray();  
  139.         int numNew = a.length;  
  140.         if (numNew == 0)  
  141.             return false;  
  142.         modCount++;     //对链表结构产生 影响的操作modCount都要加1,通过modCount可以检查是否对链表进行了并发操作  
  143.   
  144.         Entry<E> successor = (index == size ? header : entry(index));  
  145.         Entry<E> predecessor = successor.previous;  
  146.         for (int i = 0; i < numNew; i++) {   //这里不难,画一个图就出来了,主要是初始化c和修改指针  
  147.             //暂时使其next为successor,因为e会赋给前驱,而每次遍历都要修改其前驱的next  
  148.             Entry<E> e = new Entry<E>((E) a[i], successor, predecessor);    //把c中元素依次存入Entry,设置其前驱和后继。  
  149.             predecessor.next = e;   //重新设置前驱的next指针  
  150.             predecessor = e;    //让e变为前驱  
  151.         }  
  152.         successor.previous = predecessor;   //successor的前驱为c中最后一个元素的引用  
  153.   
  154.         size += numNew;     //长度加  
  155.         return true;  
  156.     }  
  157.   
  158.     /** 
  159.      * 移除链表中所有元素 
  160.      */  
  161.     public void clear() {  
  162.         Entry<E> e = header.next;  
  163.         while (e != header) {   //表示不是只有一个头结点的空链表  
  164.             Entry<E> next = e.next;  
  165.             e.next = e.previous = null//let gc work  
  166.             e.element = null;  
  167.             e = next;  
  168.         }  
  169.         header.next = header.previous = header; //初始头结点  
  170.         size = 0;  
  171.         modCount++;  
  172.     }  
  173.   
  174.     // Positional Access Operations  
  175.   
  176.     /** 
  177.      * 返回指定位置的元素时 
  178.      */  
  179.     public E get(int index) {  
  180.         return entry(index).element;  
  181.     }  
  182.   
  183.     /** 
  184.      * 设置指定位置的元素 
  185.      */  
  186.     public E set(int index, E element) {  
  187.         Entry<E> e = entry(index);  
  188.         E oldVal = e.element;  
  189.         e.element = element;  
  190.         return oldVal;  
  191.     }  
  192.   
  193.     /** 
  194.      *  
  195.      * 把指定元素添加到指定位置,需先定位到此位置的节点 
  196.      * 详情见addBefore() 
  197.      */  
  198.     public void add(int index, E element) {  
  199.         addBefore(element, (index == size ? header : entry(index)));  
  200.     }  
  201.   
  202.     /** 
  203.      * 移除指定位置的元素 
  204.      */  
  205.     public E remove(int index) {  
  206.         return remove(entry(index));  
  207.     }  
  208.   
  209.     /** 
  210.      *  
  211.      * 返回指定索引位置的Entry对象,需要依次遍历得到。 
  212.      * 这里稍做了一下优化,如果index < size/2 从前面开始遍历 
  213.      * 如果index >= size/2 从后面开始遍历 
  214.      */  
  215.     private Entry<E> entry(int index) {  
  216.         if (index < 0 || index >= size)   //index在0(包含)到size(不包含)之间,索引从0开始  
  217.             throw new IndexOutOfBoundsException("Index: " + index + ", Size: "  
  218.                     + size);  
  219.         Entry<E> e = header;  
  220.         if (index < (size >> 1)) {  
  221.             for (int i = 0; i <= index; i++)  
  222.                 e = e.next; //依次调用e.next才能得到,需调用index+1次,因为它是从头结点开始的  
  223.         } else {  
  224.             for (int i = size; i > index; i--)  
  225.                 e = e.previous; //依次调用e.previous才能得到  
  226.         }  
  227.         return e;  
  228.     }  
  229.   
  230.     // Search Operations  
  231.   
  232.     /** 
  233.      *  
  234.      * 返回o第一次出现的位置,如果在List中找不到o返回-1 
  235.      */  
  236.     public int indexOf(Object o) {  
  237.         int index = 0;  //链表的索引也是从0开始  
  238.         if (o == null) {  
  239.             for (Entry e = header.next; e != header; e = e.next) {  //从头结点开始,依次遍历  
  240.                 if (e.element == null)  
  241.                     return index;  
  242.                 index++;  
  243.             }  
  244.         } else {  
  245.             for (Entry e = header.next; e != header; e = e.next) {  
  246.                 if (o.equals(e.element))  
  247.                     return index;  
  248.                 index++;  
  249.             }  
  250.         }  
  251.         return -1;  
  252.     }  
  253.   
  254.     /** 
  255.      * 双向循环链表,从后面开始遍历即可 
  256.      */  
  257.     public int lastIndexOf(Object o) {  
  258.         int index = size;  
  259.         if (o == null) {  
  260.             for (Entry e = header.previous; e != header; e = e.previous) {  
  261.                 index--;  
  262.                 if (e.element == null)  
  263.                     return index;  
  264.             }  
  265.         } else {  
  266.             for (Entry e = header.previous; e != header; e = e.previous) {  
  267.                 index--;  
  268.                 if (o.equals(e.element))  
  269.                     return index;  
  270.             }  
  271.         }  
  272.         return -1;  
  273.     }  
  274.   
  275.     // Queue operations.有关队列的基本操作  
  276.   
  277.     /** 
  278.      * 如果链表长度不为空,获取第一个元素 
  279.      * 否则返回null 
  280.      */  
  281.     public E peek() {  
  282.         if (size == 0)  
  283.             return null;  
  284.         return getFirst();  
  285.     }  
  286.   
  287.     /** 
  288.      * 跟peek方法相似,不过这里size为0的话直接抛出异常 
  289.      */  
  290.     public E element() {  
  291.         return getFirst();  
  292.     }  
  293.   
  294.     /** 
  295.      * 如果链表长度不为空,移除第一个元素,并返回它 
  296.      * 否则返回null 
  297.      */  
  298.     public E poll() {  
  299.         if (size == 0)  
  300.             return null;  
  301.         return removeFirst();  
  302.     }  
  303.   
  304.     /** 
  305.      * 与poll方法类似,不过长度为空,即header.next = header 
  306.      * 抛出NoSuchElementException 
  307.      */  
  308.     public E remove() {  
  309.         return removeFirst();  
  310.     }  
  311.   
  312.     /** 
  313.      * 添加一个元素到链表尾部 
  314.      */  
  315.     public boolean offer(E e) {  
  316.         return add(e);  
  317.     }  
  318.   
  319.     // Deque operations  
  320.     /** 
  321.      * 添加一个元素到头结点之后,原来的第一个节点之前 
  322.      */  
  323.     public boolean offerFirst(E e) {  
  324.         addFirst(e);  
  325.         return true;  
  326.     }  
  327.   
  328.     /** 
  329.      * 在尾部添加一个元素 
  330.      */  
  331.     public boolean offerLast(E e) {  
  332.         addLast(e);  
  333.         return true;  
  334.     }  
  335.   
  336.     /** 
  337.      * 获取第一个元素,如果size为0,返回空 
  338.      * 否则返回第一个元素 
  339.      */  
  340.     public E peekFirst() {  
  341.         if (size == 0)  
  342.             return null;  
  343.         return getFirst();  
  344.     }  
  345.   
  346.     /** 
  347.      * 获取最后一个元素,如果size为0,返回空 
  348.      * 否则返回最后一个元素 
  349.      */  
  350.     public E peekLast() {  
  351.         if (size == 0)  
  352.             return null;  
  353.         return getLast();  
  354.     }  
  355.   
  356.     /** 
  357.      *  
  358.      * 移除第一个元素并返回它 
  359.      * 如果size为0则直接返回null 
  360.      */  
  361.     public E pollFirst() {  
  362.         if (size == 0)  
  363.             return null;  
  364.         return removeFirst();  
  365.     }  
  366.   
  367.     /** 
  368.      * 移除最后一个元素并返回它 
  369.      * 如果size为0则直接返回null 
  370.      */  
  371.     public E pollLast() {  
  372.         if (size == 0)  
  373.             return null;  
  374.         return removeLast();  
  375.     }  
  376.   
  377.     /** 
  378.      * 在开始位置添加一个元素 
  379.      */  
  380.     public void push(E e) {  
  381.         addFirst(e);  
  382.     }  
  383.   
  384.     /** 
  385.      * 移除第一个元素 
  386.      */  
  387.     public E pop() {  
  388.         return removeFirst();  
  389.     }  
  390.   
  391.     /** 
  392.      *  
  393.      * 移除第一次出现的指定的元素 
  394.      * 如果遍历整个List后没有找到o,则不做任何改变 
  395.      *  
  396.      */  
  397.     public boolean removeFirstOccurrence(Object o) {  
  398.         return remove(o);  
  399.     }  
  400.   
  401.     /** 
  402.      * 这个差不多,从后面开始遍历即可 
  403.      */  
  404.     public boolean removeLastOccurrence(Object o) {  
  405.         if (o == null) {  
  406.             for (Entry<E> e = header.previous; e != header; e = e.previous) {  
  407.                 if (e.element == null) {  
  408.                     remove(e);  
  409.                     return true;  
  410.                 }  
  411.             }  
  412.         } else {  
  413.             for (Entry<E> e = header.previous; e != header; e = e.previous) {  
  414.                 if (o.equals(e.element)) {  
  415.                     remove(e);  
  416.                     return true;  
  417.                 }  
  418.             }  
  419.         }  
  420.         return false;  
  421.     }  
  422.   
  423.     /** 
  424.      *  
  425.      * 返回一个list-iterator. 
  426.      */  
  427.     public ListIterator<E> listIterator(int index) {  
  428.         return new ListItr(index);  
  429.     }  
  430.       
  431.     /** 
  432.      * 重新 实现ListIterator,使其跟符合链表的特性 
  433.      * iterator方法由AbstractSequentialList实现了, 
  434.      * 但是调用的还是本ListIterator。只不过只能使用iterator接口的方法 
  435.      * */  
  436.     private class ListItr implements ListIterator<E> {  
  437.         private Entry<E> lastReturned = header;       //上一次调用next或previous返回的元素,没有调用next则为头结点  
  438.         private Entry<E> next;    //下一次调用next方法返回的元素  
  439.         private int nextIndex;  //下一次调用next返回的元素的索引  
  440.         private int expectedModCount = modCount;    //用来检测遍历过程中是否产生了并发操作  
  441.   
  442.         ListItr(int index) {    //构造器,是迭代器定位到index位置,要返回index位置的元素需调用一次next()方法时  
  443.             if (index < 0 || index > size)      
  444.                 throw new IndexOutOfBoundsException("Index: " + index  
  445.                         + ", Size: " + size);  
  446.             if (index < (size >> 1)) { //从前面开始遍历  
  447.                 next = header.next;  //这是index为0的元素  
  448.                 for (nextIndex = 0; nextIndex < index; nextIndex++)  
  449.                     next = next.next;   //最终next为第index个元素,index从0开始  
  450.             } else {        //从后面开始遍历  
  451.                 next = header;  
  452.                 for (nextIndex = size; nextIndex > index; nextIndex--)  
  453.                     next = next.previous;   //最终next为第index个元素,index从0开始  
  454.             }  
  455.         }  
  456.   
  457.         public boolean hasNext() {  //size位置可没有元素  
  458.             return nextIndex != size;  
  459.         }  
  460.   
  461.         public E next() {  
  462.             checkForComodification();  
  463.             if (nextIndex == size)  
  464.                 throw new NoSuchElementException();  
  465.   
  466.             lastReturned = next;  
  467.             next = next.next;   //这里与ArrayList中的cursor何其相似  
  468.             nextIndex++;  
  469.             return lastReturned.element;  
  470.         }  
  471.   
  472.         public boolean hasPrevious() {  
  473.             return nextIndex != 0;  
  474.         }  
  475.   
  476.         public E previous() {  
  477.             if (nextIndex == 0)  
  478.                 throw new NoSuchElementException();  
  479.   
  480.             lastReturned = next = next.previous;  
  481.             nextIndex--;  
  482.             checkForComodification();  
  483.             return lastReturned.element;  
  484.         }  
  485.   
  486.         public int nextIndex() {    //返回下一次调用next返回的元素的索引  
  487.             return nextIndex;  
  488.         }  
  489.   
  490.         public int previousIndex() {    //返回下一次调用previous返回的元素的索引  
  491.             return nextIndex - 1;  
  492.         }  
  493.   
  494.         public void remove() {  
  495.             checkForComodification();  
  496.             Entry<E> lastNext = lastReturned.next;  
  497.             try {  
  498.                 LinkedList.this.remove(lastReturned);   //移除上一层调用next()或previous返回的元素  
  499.             } catch (NoSuchElementException e) {  
  500.                 throw new IllegalStateException();  
  501.             }  
  502.             if (next == lastReturned)   //表明是调用previous后才调用remove方法  
  503.                 next = lastNext;  
  504.             else  
  505.                 nextIndex--;        //元素减少。nextIndex--  
  506.             lastReturned = header;  //重置lastReturned  
  507.             expectedModCount++;  
  508.         }  
  509.   
  510.         public void set(E e) {  
  511.             if (lastReturned == header)  
  512.                 throw new IllegalStateException();  
  513.             checkForComodification();  
  514.             lastReturned.element = e;  
  515.         }  
  516.   
  517.         public void add(E e) {  
  518.             checkForComodification();  
  519.             lastReturned = header;  
  520.             addBefore(e, next); //在上一次调用next返回的元素之后,在上次调用previous返回的元素之前添加e  
  521.             nextIndex++;    //元素增加,索引增加,保证下次调用next()不是返回添加的元素  
  522.             expectedModCount++;  
  523.         }  
  524.   
  525.         final void checkForComodification() {  
  526.             if (modCount != expectedModCount)  
  527.                 throw new ConcurrentModificationException();  
  528.         }  
  529.     }  
  530.   
  531.     /** 
  532.      * LinkedList的元素节点,保存当前节点的元素 
  533.      * 以及下一个节点,和上一个节点的引用 
  534.      * 由此看出LinkedList是一个双向链表 
  535.      */  
  536.     private static class Entry<E> {  
  537.         E element;          //当前节点元素  
  538.         Entry<E> next;        //下一个节点引用  
  539.         Entry<E> previous;    //上一个节点引用  
  540.   
  541.         Entry(E element, Entry<E> next, Entry<E> previous) {  
  542.             this.element = element;  
  543.             this.next = next;  
  544.             this.previous = previous;  
  545.         }  
  546.     }  
  547.       
  548.     /** 
  549.      *  在entry之前添加一个节点e 
  550.      *  
  551.      */  
  552.     private Entry<E> addBefore(E e, Entry<E> entry) {  
  553.         Entry<E> newEntry = new Entry<E>(e, entry, entry.previous); //新节点的前驱和后继,只有一个元素的话前驱和后继都为header  
  554.         newEntry.previous.next = newEntry;  //新节点的前驱的后继为新节点,只包含newEntry一个元素的话修改的是头结点的next  
  555.         newEntry.next.previous = newEntry;  //新节点的后继的前驱为新节点,只包含newEntry一个元素的话修改的是头结点的previous  
  556.         size++;  
  557.         modCount++;  
  558.         return newEntry;  
  559.     }  
  560.   
  561.     /** 
  562.      * 移除指定节点  
  563.      */  
  564.     private E remove(Entry<E> e) {  
  565.         if (e == header)  
  566.             throw new NoSuchElementException();  
  567.   
  568.         E result = e.element;  
  569.         //修改节点指针  
  570.         e.previous.next = e.next;   //e的前驱的后继等于e的后继  
  571.         e.next.previous = e.previous;   //e的后继的前驱等于e的前驱  
  572.         e.next = e.previous = null//let gc work  
  573.         e.element = null;  
  574.         size--;     //size--  
  575.         modCount++;  
  576.         return result;  
  577.     }  
  578.   
  579.     /** 
  580.      * 逆序返回所有元素的迭代器 
  581.      */  
  582.     public Iterator<E> descendingIterator() {  
  583.         return new DescendingIterator();  
  584.     }  
  585.   
  586.     /** Adapter to provide descending iterators via ListItr.previous */  
  587.     private class DescendingIterator implements Iterator {  
  588.         final ListItr itr = new ListItr(size());  
  589.   
  590.         public boolean hasNext() {  
  591.             return itr.hasPrevious();  
  592.         }  
  593.   
  594.         public E next() {  
  595.             return itr.previous();  
  596.         }  
  597.   
  598.         public void remove() {  
  599.             itr.remove();  
  600.         }  
  601.     }  
  602.   
  603.     /** 
  604.      * 返回一个LikedList的浅拷贝对象 
  605.      */  
  606.     public Object clone() {  
  607.         LinkedList<E> clone = null;  
  608.         try {  
  609.             clone = (LinkedList<E>) super.clone();  
  610.         } catch (CloneNotSupportedException e) {  
  611.             throw new InternalError();  
  612.         }  
  613.   
  614.         // Put clone into "virgin" state,即重置其为初始状态  
  615.         clone.header = new Entry<E>(nullnullnull);  
  616.         clone.header.next = clone.header.previous = clone.header;  
  617.         clone.size = 0;  
  618.         clone.modCount = 0;  
  619.   
  620.         // 初始化克隆对象  
  621.         for (Entry<E> e = header.next; e != header; e = e.next)  
  622.             clone.add(e.element);  
  623.   
  624.         return clone;  
  625.     }  
  626.   
  627.     /** 
  628.      * 返回一个新建对象数组,包含链表中所有元素 
  629.      */  
  630.     public Object[] toArray() {  
  631.         Object[] result = new Object[size]; //新建一size长度对象数组  
  632.         int i = 0;  
  633.         for (Entry<E> e = header.next; e != header; e = e.next)   //遍历赋值  
  634.             result[i++] = e.element;  
  635.         return result;  
  636.     }  
  637.   
  638.     /** 
  639.      * 所有toArray方法都是一个思想... 
  640.      * 只是遍历方式不同 
  641.      * */  
  642.     public <T> T[] toArray(T[] a) {  
  643.         if (a.length < size) //如果指定数组长度小于size,新建一数组  
  644.             a = (T[]) java.lang.reflect.Array.newInstance(a.getClass()  
  645.                     .getComponentType(), size);  
  646.         int i = 0;  
  647.         Object[] result = a;  
  648.         for (Entry<E> e = header.next; e != header; e = e.next)  
  649.             result[i++] = e.element;  
  650.   
  651.         if (a.length > size) //同ArrayList  
  652.             a[size] = null;  
  653.   
  654.         return a;  
  655.     }  
  656.   
  657.     private static final long serialVersionUID = 876323262645176354L;  
  658.   
  659.     /** 
  660.      * 序列化LikedList,保存其状态 
  661.      */  
  662.     private void writeObject(java.io.ObjectOutputStream s)  
  663.             throws java.io.IOException {  
  664.         // Write out any hidden serialization magic  
  665.         //添加一些序列化的额外信息,表明它是一个序列化的文件  
  666.         s.defaultWriteObject();  
  667.   
  668.         // 写长度  
  669.         s.writeInt(size);  
  670.   
  671.         // 写元素  
  672.         for (Entry e = header.next; e != header; e = e.next)  
  673.             s.writeObject(e.element);  
  674.     }  
  675.   
  676.     /** 
  677.      * 从流中读取 
  678.      */  
  679.     private void readObject(java.io.ObjectInputStream s)  
  680.             throws java.io.IOException, ClassNotFoundException {  
  681.         // Read in any hidden serialization magic  
  682.         s.defaultReadObject();  
  683.   
  684.         // 读长度  
  685.         int size = s.readInt();  
  686.   
  687.         // 初始化header  
  688.         header = new Entry<E>(nullnullnull);  
  689.         header.next = header.previous = header;  
  690.   
  691.         // 按顺序写入所有元素  
  692.         for (int i = 0; i < size; i++)  
  693.             addBefore((E) s.readObject(), header);  
  694.     }  
  695. }  




三。HashMap(数组加链表的结合体)
Java代码   收藏代码
  1. /** 
  2.  * 作用:用于实现快速查找 
  3.  * HashMap实现的数据结构:动态数组和链表的结合体 
  4.  * */  
  5. public class HashMap<K, V> extends AbstractMap<K, V> implements Map<K, V>,  
  6.         Cloneable, Serializable {  
  7.   
  8.     /** 
  9.      * 默认初始数组容量,必须为2的幂 
  10.      */  
  11.     static final int DEFAULT_INITIAL_CAPACITY = 16;  
  12.   
  13.     /** 
  14.      * 
  15.      * 最大容量为1 * 2^30 即2的30次方 
  16.      */  
  17.     static final int MAXIMUM_CAPACITY = 1 << 30;  
  18.   
  19.     /** 
  20.      *  
  21.      * hashMap的加载系数,当数组中的元素增多时,通过hash函数算出的数组下标 
  22.      * 相同几率增加。为保证查找的效率,当数组中的元素超过 
  23.      * load_factor * table.length 时就要扩充容量 
  24.      * 默认加载系数为0.75 
  25.      */  
  26.     static final float DEFAULT_LOAD_FACTOR = 0.75f;  
  27.   
  28.     /** 
  29.      *  
  30.      * 数组存放Entry对象,单向链表的第一个元素, 
  31.      * 通过它可以遍历整个链表。 
  32.      * table长度会在需要时进行扩充,table长度始终为2的幂 
  33.      */  
  34.     transient Entry[] table;  
  35.   
  36.     /** 
  37.      * key-value键值对个数 
  38.      */  
  39.     transient int size;  
  40.   
  41.     /** 
  42.      * HashMap size >= threshlod时就扩充数组容量 
  43.      */  
  44.     int threshold;  
  45.   
  46.     /** 
  47.      * hash表加载因子 
  48.      */  
  49.     final float loadFactor;  
  50.   
  51.     /** 
  52.      *  
  53.      * hash表发生结构性改变的次数,这些方法包括,put,remove等对size进行改变的操作 
  54.      * 用iterator遍历时可以用来检测是否对HashMap进行了并发操作 
  55.      */  
  56.     transient volatile int modCount;  
  57.   
  58.     /** 
  59.      * 根据指定的初始容量和加载系数构建hashMap 
  60.      * 初始容量如果不是2的幂,会被构造成2的幂 
  61.      */  
  62.     public HashMap(int initialCapacity, float loadFactor) {  
  63.         if (initialCapacity < 0)   
  64.             throw new IllegalArgumentException("Illegal initial capacity: "  
  65.                     + initialCapacity);  
  66.         if (initialCapacity > MAXIMUM_CAPACITY)  
  67.             initialCapacity = MAXIMUM_CAPACITY;  
  68.         if (loadFactor <= 0 || Float.isNaN(loadFactor))  
  69.             throw new IllegalArgumentException("Illegal load factor: "  
  70.                     + loadFactor);  
  71.   
  72.         //找到一个2的幂的数,使其大于等于初始容量  
  73.         int capacity = 1;  
  74.         while (capacity < initialCapacity)     
  75.             capacity <<= 1;           // capacity = capacity << 1,左移一位   
  76.   
  77.         this.loadFactor = loadFactor;  
  78.         threshold = (int) (capacity * loadFactor);  
  79.         table = new Entry[capacity];  
  80.         init(); //所有构造方法都含有此空方法,做一些其他初始化操作。根据业务要求,可由其子类实现  
  81.     }  
  82.   
  83.     /** 
  84.      * 根据指定容量与默认加载系数构建HashMap 
  85.      */  
  86.     public HashMap(int initialCapacity) {  
  87.         this(initialCapacity, DEFAULT_LOAD_FACTOR);  
  88.     }  
  89.   
  90.     /** 
  91.      * 采用默认容量16与默认加载系数0.75构建HashMap 
  92.      */  
  93.     public HashMap() {  
  94.         this.loadFactor = DEFAULT_LOAD_FACTOR;  
  95.         threshold = (int) (DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);  
  96.         table = new Entry[DEFAULT_INITIAL_CAPACITY];  
  97.         init();  
  98.     }  
  99.   
  100.     /** 
  101.      *  
  102.      * 根据指定Map中的键值对,默认加载因子构建HashMap 
  103.      */  
  104.     public HashMap(Map<? extends K, ? extends V> m) {  
  105.         this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1//size要小于容量*0.75  
  106.                 DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);  
  107.         putAllForCreate(m);   
  108.     }  
  109.   
  110.     // internal utilities  
  111.   
  112.     /** 
  113.      * 
  114.      * 在new table之后,在添加元素之前被调用 
  115.      */  
  116.     void init() {  
  117.     }  
  118.   
  119.     /** 
  120.      *  
  121.      * hash算法,根据key的hashCode计算其hash值 
  122.      * 此算法看的一知半解,大家有兴趣可以查看其它资料 
  123.      * >>>无符号右移     ^按位异或 
  124.      */  
  125.     static int hash(int h) {  
  126.         // This function ensures that hashCodes that differ only by  
  127.         // constant multiples at each bit position have a bounded  
  128.         // number of collisions (approximately 8 at default load factor).  
  129.         h ^= (h >>> 20) ^ (h >>> 12);  
  130.         return h ^ (h >>> 7) ^ (h >>> 4);  
  131.     }  
  132.   
  133.     /** 
  134.      * 根据hash值与数组长度计算其数组索引。 
  135.      * length为2的幂,使不同hash通过h&(length-1)产生的索引尽量不同,即减少碰撞。 
  136.      * 如果产生的索引都不同,通过找到索引就可以直接找到value,而不需要遍历链表。 
  137.      * 可以使产生的索引始终在table索引范围之内 
  138.      * 此方法详细解析可见:http://www.iteye.com/topic/539465 
  139.      */  
  140.     static int indexFor(int h, int length) {  
  141.         return h & (length - 1);  
  142.     }  
  143.   
  144.     /** 
  145.      * 键值对数目 
  146.      */  
  147.     public int size() {  
  148.         return size;  
  149.     }  
  150.   
  151.     /** 
  152.      * 判断hashMap是否为空 
  153.      */  
  154.     public boolean isEmpty() {  
  155.         return size == 0;  
  156.     }  
  157.   
  158.     /** 
  159.      *  
  160.      * 通过key值获得value,如果没有找到此key则返回null。 
  161.      * 不过返回null也可能是其value为null 
  162.      * 通过contain方法可判断Map中是否含有此键 
  163.      *  
  164.      */  
  165.     public V get(Object key) {  
  166.         if (key == null)    //空键另外处理  
  167.             return getForNullKey();  
  168.         int hash = hash(key.hashCode());  
  169.         //定位到index,并查看e的下一个节点是否为null,否则继续遍历  
  170.         for (Entry<K, V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) {  
  171.             Object k;  
  172.             if (e.hash == hash && ((k = e.key) == key || key.equals(k)))  
  173.                 return e.value;  
  174.         }  
  175.         return null;  
  176.     }  
  177.   
  178.     /** 
  179.      *  
  180.      * 空键的hash值为0,所以其数组中的索引为0. 
  181.      * 独立把此方法分离出来是为了提高两个最常用的方法get和put的性能, 
  182.      * 但在其它情况下此方法被合并了. 
  183.      */  
  184.     private V getForNullKey() {  
  185.         for (Entry<K, V> e = table[0]; e != null; e = e.next) {  
  186.             if (e.key == null)  
  187.                 return e.value;  
  188.         }  
  189.         return null;  
  190.     }  
  191.   
  192.     /** 
  193.      * 如果Map中含有此key返回true. 
  194.      * 具体见getEntry. 
  195.      */  
  196.     public boolean containsKey(Object key) {  
  197.         return getEntry(key) != null;  
  198.     }  
  199.   
  200.     /** 
  201.      *  
  202.      * 通过返回Entry而不是value可确保Map中是否含有此key 
  203.      */  
  204.     final Entry<K, V> getEntry(Object key) {  
  205.         int hash = (key == null) ? 0 : hash(key.hashCode());  
  206.         for (Entry<K, V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) {  
  207.             Object k;  
  208.             if (e.hash == hash  
  209.                     && ((k = e.key) == key || (key != null && key.equals(k))))  
  210.                 return e;  
  211.         }  
  212.         return null;  
  213.     }  
  214.   
  215.     /** 
  216.      *  
  217.      * replaced. 
  218.      * 通过指定的key值存储指定value,如果Map中含有此key则用指定value替换old value 
  219.      */  
  220.     public V put(K key, V value) {  
  221.         if (key == null)  
  222.             return putForNullKey(value);  
  223.         int hash = hash(key.hashCode());  
  224.         int i = indexFor(hash, table.length);  
  225.         for (Entry<K, V> e = table[i]; e != null; e = e.next) {  
  226.             Object k;  
  227.             if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {  
  228.                 V oldValue = e.value;  
  229.                 e.value = value;  
  230.                 e.recordAccess(this);   //当你调用put并在替换老值时会调用此方法,假如你在这个时候想做一些额外操作可继承Entry重写此方法  
  231.                 return oldValue;  
  232.             }  
  233.         }  
  234.   
  235.         modCount++;  
  236.         addEntry(hash, key, value, i);  
  237.         return null;  
  238.     }  
  239.   
  240.   
  241.     private V putForNullKey(V value) {  
  242.         for (Entry<K, V> e = table[0]; e != null; e = e.next) {  
  243.             if (e.key == null) {    //如果含有此null key替换老值  
  244.                 V oldValue = e.value;  
  245.                 e.value = value;  
  246.                 e.recordAccess(this);  
  247.                 return oldValue;  
  248.             }  
  249.         }  
  250.         modCount++;  
  251.         addEntry(0null, value, 0);    //否则添加此Entry到数组  
  252.         return null;  
  253.     }  
  254.   
  255.     /** 
  256.      *  
  257.      * 此方法用来替代put方法,不会调整table大小。 
  258.      * 此方法在确认map键值对个数始终小于table.length * load_factor, 
  259.      * 添加元素时调用。主要是为了提高性能 
  260.      */  
  261.     private void putForCreate(K key, V value) {  
  262.         int hash = (key == null) ? 0 : hash(key.hashCode());  
  263.         int i = indexFor(hash, table.length);  
  264.   
  265.         /** 
  266.          *  
  267.          * 查看是否存在同样的key值,如果有就替换其value 
  268.          */  
  269.         for (Entry<K, V> e = table[i]; e != null; e = e.next) {  
  270.             Object k;  
  271.             if (e.hash == hash  
  272.                     && ((k = e.key) == key || (key != null && key.equals(k)))) {  
  273.                 e.value = value;  
  274.                 return;  
  275.             }  
  276.         }  
  277.         //否则添加一个Entry对象  
  278.         createEntry(hash, key, value, i);  
  279.     }  
  280.   
  281.     /** 
  282.      * 依次遍历添加 
  283.      * */  
  284.     private void putAllForCreate(Map<? extends K, ? extends V> m) {  
  285.         for (Iterator<? extends Map.Entry<? extends K, ? extends V>> i = m  
  286.                 .entrySet().iterator(); i.hasNext();) {  
  287.             Map.Entry<? extends K, ? extends V> e = i.next();  
  288.             putForCreate(e.getKey(), e.getValue());  
  289.         }  
  290.     }  
  291.   
  292.     /** 
  293.      *  
  294.      * 当HashMap中元素越来越多时,发生碰撞的几率增大,为提高效率,当元素超过 
  295.      * threshold时就要对数组进行扩充,扩充后,原数组中所有数据都要重新计算 
  296.      * 其在新数组中的位置,所以每扩充一次对性能影响是非常大的。 
  297.      */  
  298.     void resize(int newCapacity) {  
  299.         Entry[] oldTable = table;  
  300.         int oldCapacity = oldTable.length;  
  301.         if (oldCapacity == MAXIMUM_CAPACITY) {  //如果数组容量已经最大,不再扩充。  
  302.             threshold = Integer.MAX_VALUE;      //使threshold = Integer.MAX_VALUE,使resize方法不再被调用  
  303.             return;  
  304.         }  
  305.   
  306.         Entry[] newTable = new Entry[newCapacity];  
  307.         transfer(newTable);  
  308.         table = newTable;  
  309.         threshold = (int) (newCapacity * loadFactor);  
  310.     }  
  311.   
  312.     /** 
  313.      *  
  314.      * 把table中所有的Entry对象转移到newTabel 
  315.      */  
  316.     void transfer(Entry[] newTable) {  
  317.         Entry[] src = table;  
  318.         int newCapacity = newTable.length;  
  319.         for (int j = 0; j < src.length; j++) {  
  320.             Entry<K, V> e = src[j];  
  321.             if (e != null) {  
  322.                 src[j] = null;  //只置空第一个节点即可,因为此节点存在数组中  
  323.                 do {  
  324.                     Entry<K, V> next = e.next;  
  325.                     int i = indexFor(e.hash, newCapacity);  //根据新容量重新计算index  
  326.                     e.next = newTable[i];   //最后添加的节点放最前面  
  327.                     newTable[i] = e;  
  328.                     e = next;  
  329.                 } while (e != null);  
  330.             }  
  331.         }  
  332.     }  
  333.   
  334.     /** 
  335.      * 
  336.      * 把所有元素从知道map中复制到本map 
  337.      */  
  338.     public void putAll(Map<? extends K, ? extends V> m) {  
  339.         int numKeysToBeAdded = m.size();  
  340.         if (numKeysToBeAdded == 0)  
  341.             return;  
  342.   
  343.         /* 
  344.          *  
  345.          * 如果numKeysToBeAdded大于或等于threshold就扩展map 
  346.          * 这是一个保守的方法。本来的条件应该是(m.size() + size) >= threshold, 
  347.          * 但是如果所有被添加的元素的key值在本map中都存在,map扩充的容量将是 
  348.          * 最佳容量的两倍。这极大的浪费了空间,所以采用此保守的方法计算newCapacity。 
  349.          * 否则不再此处扩充就在put方法中进行扩充 
  350.          */  
  351.         if (numKeysToBeAdded > threshold) {  
  352.             int targetCapacity = (int) (numKeysToBeAdded / loadFactor + 1);  
  353.             if (targetCapacity > MAXIMUM_CAPACITY)  
  354.                 targetCapacity = MAXIMUM_CAPACITY;  
  355.             int newCapacity = table.length;  
  356.             while (newCapacity < targetCapacity)  
  357.                 newCapacity <<= 1;      
  358.             if (newCapacity > table.length)  
  359.                 resize(newCapacity);  
  360.         }  
  361.   
  362.         //依次遍历添加  
  363.         for (Iterator<? extends Map.Entry<? extends K, ? extends V>> i = m  
  364.                 .entrySet().iterator(); i.hasNext();) {  
  365.             Map.Entry<? extends K, ? extends V> e = i.next();  
  366.             put(e.getKey(), e.getValue());  
  367.         }  
  368.     }  
  369.   
  370.     /** 
  371.      * 根据知道key移除键值对,返回移除的元素 
  372.      */  
  373.     public V remove(Object key) {  
  374.         Entry<K, V> e = removeEntryForKey(key);  
  375.         return (e == null ? null : e.value);  
  376.     }  
  377.   
  378.     /** 
  379.      * 根据key移除Entry对象 
  380.      */  
  381.     final Entry<K, V> removeEntryForKey(Object key) {  
  382.         int hash = (key == null) ? 0 : hash(key.hashCode());  
  383.         int i = indexFor(hash, table.length);  
  384.         Entry<K, V> prev = table[i];  
  385.         Entry<K, V> e = prev;  
  386.   
  387.         while (e != null) {  
  388.             Entry<K, V> next = e.next;  
  389.             Object k;  
  390.             if (e.hash == hash  
  391.                     && ((k = e.key) == key || (key != null && key.equals(k)))) {  
  392.                 modCount++;  
  393.                 size--;  
  394.                 if (prev == e)  //表明链表只有一个Entry对象  
  395.                     table[i] = next;  
  396.                 else  
  397.                     prev.next = next;   //修改指针  
  398.                 e.recordRemoval(this);  //在移除元素时调用  
  399.                 return e;  
  400.             }  
  401.             prev = e;  
  402.             e = next;  
  403.         }  
  404.   
  405.         return e;  
  406.     }  
  407.   
  408.     /** 
  409.      * 同remove方法基本相似 
  410.      */  
  411.     final Entry<K, V> removeMapping(Object o) {  
  412.         if (!(o instanceof Map.Entry))  
  413.             return null;  
  414.   
  415.         Map.Entry<K, V> entry = (Map.Entry<K, V>) o;  
  416.         Object key = entry.getKey();  
  417.         int hash = (key == null) ? 0 : hash(key.hashCode());  
  418.         int i = indexFor(hash, table.length);  
  419.         Entry<K, V> prev = table[i];  
  420.         Entry<K, V> e = prev;  
  421.   
  422.         while (e != null) {  
  423.             Entry<K, V> next = e.next;  
  424.             if (e.hash == hash && e.equals(entry)) {  
  425.                 modCount++;  
  426.                 size--;  
  427.                 if (prev == e)  
  428.                     table[i] = next;  
  429.                 else  
  430.                     prev.next = next;  
  431.                 e.recordRemoval(this);  
  432.                 return e;  
  433.             }  
  434.             prev = e;  
  435.             e = next;  
  436.         }  
  437.   
  438.         return e;  
  439.     }  
  440.   
  441.     /** 
  442.      * 移除所有元素 
  443.      */  
  444.     public void clear() {  
  445.         modCount++;  
  446.         Entry[] tab = table;  
  447.         for (int i = 0; i < tab.length; i++)  
  448.             tab[i] = null;  //只要把数组置空即可  
  449.         size = 0;  
  450.     }  
  451.   
  452.     /** 
  453.      * 是否包含次value 
  454.      */  
  455.     public boolean containsValue(Object value) {  
  456.         if (value == null)  
  457.             return containsNullValue();  
  458.   
  459.         Entry[] tab = table;  
  460.         for (int i = 0; i < tab.length; i++)  
  461.             for (Entry e = tab[i]; e != null; e = e.next)  
  462.                 if (value.equals(e.value))  
  463.                     return true;  
  464.         return false;  
  465.     }  
  466.   
  467.     /** 
  468.      * 是否包含空值 
  469.      */  
  470.     private boolean containsNullValue() {  
  471.         Entry[] tab = table;  
  472.         for (int i = 0; i < tab.length; i++)  
  473.             for (Entry e = tab[i]; e != null; e = e.next)  
  474.                 if (e.value == null)  
  475.                     return true;  
  476.         return false;  
  477.     }  
  478.   
  479.     /** 
  480.      * 返回HashMap的浅拷贝实例 
  481.      */  
  482.     public Object clone() {  
  483.         HashMap<K, V> result = null;  
  484.         try {  
  485.             result = (HashMap<K, V>) super.clone();  
  486.         } catch (CloneNotSupportedException e) {  
  487.             // assert false;  
  488.         }  
  489.           
  490.         result.table = new Entry[table.length];  
  491.         result.entrySet = null;       
  492.         result.modCount = 0;  
  493.         result.size = 0;  
  494.         result.init();  
  495.         result.putAllForCreate(this);   //依次添加本map所有元素到浅拷贝的map实例中  
  496.   
  497.         return result;  
  498.     }  
  499.   
  500.     static class Entry<K, V> implements Map.Entry<K, V> {  
  501.         final K key;  
  502.         V value;  
  503.         Entry<K, V> next;  
  504.         final int hash;  
  505.   
  506.         /** 
  507.          * Creates new entry. 
  508.          */  
  509.         Entry(int h, K k, V v, Entry<K, V> n) {  
  510.             value = v;  
  511.             next = n;  
  512.             key = k;  
  513.             hash = h;  
  514.         }  
  515.   
  516.         public final K getKey() {  
  517.             return key;  
  518.         }  
  519.   
  520.         public final V getValue() {  
  521.             return value;  
  522.         }  
  523.   
  524.         public final V setValue(V newValue) {  
  525.             V oldValue = value;  
  526.             value = newValue;  
  527.             return oldValue;  
  528.         }  
  529.   
  530.         //Entry的equals方法,键值相等即Entry对象相等  
  531.         public final boolean equals(Object o) {  
  532.             if (!(o instanceof Map.Entry))  
  533.                 return false;  
  534.             Map.Entry e = (Map.Entry) o;  
  535.             Object k1 = getKey();  
  536.             Object k2 = e.getKey();  
  537.             if (k1 == k2 || (k1 != null && k1.equals(k2))) {  
  538.                 Object v1 = getValue();  
  539.                 Object v2 = e.getValue();  
  540.                 if (v1 == v2 || (v1 != null && v1.equals(v2)))  
  541.                     return true;  
  542.             }  
  543.             return false;  
  544.         }  
  545.   
  546.         /** 
  547.          * 重写hashCode方法,异或key与value的hashCode值 
  548.          */  
  549.         public final int hashCode() {  
  550.             return (key == null ? 0 : key.hashCode())  
  551.                     ^ (value == null ? 0 : value.hashCode());  
  552.         }  
  553.   
  554.         public final String toString() {  
  555.             return getKey() + "=" + getValue();  
  556.         }  
  557.   
  558.         /** 
  559.          * 
  560.          * 当添加一键值对,发现键已存在时调用此方法 
  561.          *  可以继承Entry对象重写此方法 
  562.          */  
  563.         void recordAccess(HashMap<K, V> m) {  
  564.         }  
  565.   
  566.         /** 
  567.          * 当有Entry对象被移除时,此方法被调用。 
  568.          * 可以继承Entry对象重写此方法 
  569.          */  
  570.         void recordRemoval(HashMap<K, V> m) {  
  571.         }  
  572.     }  
  573.   
  574.     /** 
  575.      *  
  576.      * 如果适当此方法会resize table 
  577.      */  
  578.     void addEntry(int hash, K key, V value, int bucketIndex) {  
  579.         Entry<K, V> e = table[bucketIndex];      
  580.         table[bucketIndex] = new Entry<K, V>(hash, key, value, e);  
  581.         if (size++ >= threshold) //如果size超过threshold就调整数组容量大小为原来的两倍  
  582.             resize(2 * table.length);  
  583.     }  
  584.   
  585.     /** 
  586.      * 
  587.      * 与addEntry方法类似。但是方法不需要担心容量的扩充 
  588.      */  
  589.     void createEntry(int hash, K key, V value, int bucketIndex) {  
  590.         Entry<K, V> e = table[bucketIndex];   //如果此节点已经有一个Entry对象,返回e,否则返回null  
  591.         table[bucketIndex] = new Entry<K, V>(hash, key, value, e);    //以新加入的节点作为第一个节点  
  592.         size++;  
  593.     }  
  594.   
  595.     /** 
  596.      * 抽象类,next方法由其子类实现, 
  597.      * 不同的next方法返回不同的迭代器 
  598.      * 包括key,value,keySet迭代器 
  599.      * */  
  600.     private abstract class HashIterator<E> implements Iterator<E> {  
  601.         Entry<K, V> next; // next entry to return  
  602.         int expectedModCount; // For fast-fail  
  603.         int index; // current slot  
  604.         Entry<K, V> current; // current entry  
  605.   
  606.         HashIterator() {  
  607.             expectedModCount = modCount;  
  608.             if (size > 0) { // advance to first entry  
  609.                 Entry[] t = table;  
  610.                 //遍历直到获取第一个Entry对象,因为有的索引可能为空  
  611.                 while (index < t.length && (next = t[index++]) == null)   
  612.                     ;  
  613.             }  
  614.         }  
  615.   
  616.         public final boolean hasNext() {  
  617.             return next != null;  
  618.         }  
  619.   
  620.         /** 
  621.          * 返回下一个Entry对象 
  622.          * */  
  623.         final Entry<K, V> nextEntry() {  
  624.             if (modCount != expectedModCount)  
  625.                 throw new ConcurrentModificationException();  
  626.             Entry<K, V> e = next;  
  627.             if (e == null)  
  628.                 throw new NoSuchElementException();  
  629.   
  630.             if ((next = e.next) == null) {  
  631.                 Entry[] t = table;  
  632.                 //继续找不为空的索引中的Entry对象  
  633.                 while (index < t.length && (next = t[index++]) == null)  
  634.                     ;  
  635.             }  
  636.             current = e;  
  637.             return e;  
  638.         }  
  639.   
  640.         /** 
  641.          * 移除当前Entry对象,即调用nextEntry返回的Entry对象 
  642.          */  
  643.         public void remove() {  
  644.             if (current == null)  
  645.                 throw new IllegalStateException();  
  646.             if (modCount != expectedModCount)  
  647.                 throw new ConcurrentModificationException();  
  648.             Object k = current.key;  
  649.             current = null;  
  650.             HashMap.this.removeEntryForKey(k);  //此方法会改变modCount  
  651.             expectedModCount = modCount;    //所以可以用此语句检测是否产生了并发操作  
  652.         }  
  653.   
  654.     }  
  655.   
  656.     //依次重写next方法,返回不同的迭代器。  
  657.       
  658.     private final class ValueIterator extends HashIterator<V> {  
  659.         public V next() {  
  660.             return nextEntry().value;  
  661.         }  
  662.     }  
  663.   
  664.     private final class KeyIterator extends HashIterator<K> {  
  665.         public K next() {  
  666.             return nextEntry().getKey();  
  667.         }  
  668.     }  
  669.   
  670.     private final class EntryIterator extends HashIterator<Map.Entry<K, V>> {  
  671.         public Map.Entry<K, V> next() {  
  672.             return nextEntry();  
  673.         }  
  674.     }  
  675.   
  676.     // Subclass overrides these to alter behavior of views' iterator() method  
  677.     Iterator<K> newKeyIterator() {  
  678.         return new KeyIterator();  
  679.     }  
  680.   
  681.     Iterator<V> newValueIterator() {  
  682.         return new ValueIterator();  
  683.     }  
  684.   
  685.     Iterator<Map.Entry<K, V>> newEntryIterator() {  
  686.         return new EntryIterator();  
  687.     }  
  688.   
  689.     // Views  
  690.   
  691.     private transient Set<Map.Entry<K, V>> entrySet = null;  
  692.   
  693.     /** 
  694.      * 返回一个key集。 
  695.      * 此Set集合只在第一次调用keySet()时被创建,此后返回的都是同一个Set。  
  696.      * 此方法不是线程安全的,大量线程多次调用此方法返回的可能不是同一个Set(可能是重新new的) 
  697.      *  
  698.      * 对map的修改会反应到Set当中,相反,对Set中key进行移除操作,比如  
  699.      * Iterator.remove,Set.remove ,removeAll,retainAll,clear等操作时被移除的键  
  700.      * 和它相关联的值也将从map中被移除,但是此Set不支持任何添加操作  
  701.      */  
  702.     public Set<K> keySet() {  
  703.         Set<K> ks = keySet;  
  704.         return (ks != null ? ks : (keySet = new KeySet()));  
  705.     }  
  706.   
  707.     private final class KeySet extends AbstractSet<K> {  
  708.         public Iterator<K> iterator() {  
  709.             return newKeyIterator();  
  710.         }  
  711.   
  712.         public int size() {  
  713.             return size;  
  714.         }  
  715.   
  716.         public boolean contains(Object o) {  
  717.             return containsKey(o);  
  718.         }  
  719.   
  720.         /** 
  721.          * 重写了Set的remove方法, 
  722.          * 父类remove都是调用迭代器的remove方法 
  723.          * */  
  724.         public boolean remove(Object o) {  
  725.             return HashMap.this.removeEntryForKey(o) != null;  
  726.         }  
  727.   
  728.         public void clear() {  
  729.             HashMap.this.clear();  
  730.         }  
  731.     }  
  732.   
  733.     /** 
  734.      * 同上 
  735.      */  
  736.     public Collection<V> values() {  
  737.         Collection<V> vs = values;  
  738.         return (vs != null ? vs : (values = new Values()));  
  739.     }  
  740.   
  741.     private final class Values extends AbstractCollection<V> {  
  742.         public Iterator<V> iterator() {  
  743.             return newValueIterator();  
  744.         }  
  745.   
  746.         public int size() {  
  747.             return size;  
  748.         }  
  749.   
  750.         public boolean contains(Object o) {  
  751.             return containsValue(o);  
  752.         }  
  753.   
  754.         public void clear() {  
  755.             HashMap.this.clear();  
  756.         }  
  757.     }  
  758.   
  759.     /** 
  760.      * 同上 
  761.      */  
  762.     public Set<Map.Entry<K, V>> entrySet() {  
  763.         return entrySet0();  
  764.     }  
  765.   
  766.     private Set<Map.Entry<K, V>> entrySet0() {  
  767.         Set<Map.Entry<K, V>> es = entrySet;  
  768.         return es != null ? es : (entrySet = new EntrySet());  
  769.     }  
  770.   
  771.     private final class EntrySet extends AbstractSet<Map.Entry<K, V>> {  
  772.         public Iterator<Map.Entry<K, V>> iterator() {  
  773.             return newEntryIterator();  
  774.         }  
  775.   
  776.         public boolean contains(Object o) {  
  777.             if (!(o instanceof Map.Entry))  
  778.                 return false;  
  779.             Map.Entry<K, V> e = (Map.Entry<K, V>) o;  
  780.             Entry<K, V> candidate = getEntry(e.getKey());  
  781.             return candidate != null && candidate.equals(e);  
  782.         }  
  783.   
  784.         public boolean remove(Object o) {  
  785.             return removeMapping(o) != null;  
  786.         }  
  787.   
  788.         public int size() {  
  789.             return size;  
  790.         }  
  791.   
  792.         public void clear() {  
  793.             HashMap.this.clear();  
  794.         }  
  795.     }  
  796.   
  797.     /** 
  798.      * 序列化hashMap对象 
  799.      */  
  800.     private void writeObject(java.io.ObjectOutputStream s) throws IOException {  
  801.         Iterator<Map.Entry<K, V>> i = (size > 0) ? entrySet0().iterator()  
  802.                 : null;  
  803.   
  804.         // 写入默认信息  
  805.         s.defaultWriteObject();  
  806.   
  807.         // 写入可以存储的容量  
  808.         s.writeInt(table.length);  
  809.   
  810.         // 写入实际长度  
  811.         s.writeInt(size);  
  812.   
  813.         // Write out keys and values (alternating)  
  814.         if (i != null) {  
  815.             while (i.hasNext()) {   //依次写入键值对  
  816.                 Map.Entry<K, V> e = i.next();  
  817.                 s.writeObject(e.getKey());  
  818.                 s.writeObject(e.getValue());  
  819.             }  
  820.         }  
  821.     }  
  822.   
  823.     private static final long serialVersionUID = 362498820763181265L;  
  824.   
  825.     /** 
  826.      * 读出HashMap对象 
  827.      */  
  828.     private void readObject(java.io.ObjectInputStream s) throws IOException,  
  829.             ClassNotFoundException {  
  830.         //读出默认信息  
  831.         s.defaultReadObject();  
  832.   
  833.         // 读容量  
  834.         int numBuckets = s.readInt();  
  835.         table = new Entry[numBuckets];  
  836.   
  837.         init(); // Give subclass a chance to do its thing.  
  838.   
  839.         // 读长度  
  840.         int size = s.readInt();  
  841.   
  842.         //读键值对,并还原HashMap元素  
  843.         for (int i = 0; i < size; i++) {  
  844.             K key = (K) s.readObject();  
  845.             V value = (V) s.readObject();  
  846.             putForCreate(key, value);  
  847.         }  
  848.     }  
  849.   
  850.     // These methods are used when serializing HashSets  
  851.     int capacity() {  
  852.         return table.length;  
  853.     }  
  854.   
  855.     float loadFactor() {  
  856.         return loadFactor;  
  857.     }  
  858. }  



四。HashSet
Java代码   收藏代码
  1. /** 
  2.  * 散列集(hashSet),就是不存在重复元素的集合。 
  3.  * HashSet是在HashMap的基础上实现的, 
  4.  * 以HashSet的元素做Key值使其值不会重复 
  5.  * */  
  6. public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable,  
  7.         java.io.Serializable {  
  8.     static final long serialVersionUID = -5024744406713321676L;  
  9.   
  10.     private transient HashMap<E, Object> map;  
  11.   
  12.   
  13.     //以Object作为虚假的Value值  
  14.     private static final Object PRESENT = new Object();  
  15.   
  16.     /** 
  17.      *  
  18.      * 构造一个新的,空Set集; 
  19.      * 实际是构造一个默认初始容量为16,加载因子为0.75的空HashMap 
  20.      */  
  21.     public HashSet() {  
  22.         map = new HashMap<E, Object>();  
  23.     }  
  24.   
  25.     /** 
  26.      * 
  27.      * 构造一个包含指定集合c中所有元素的新的Set集。 
  28.      * 实际是构造包含集合c中所有元素的HashMap. 
  29.      * 初始大小必须大于容量*0.75 
  30.      *  
  31.      */  
  32.     public HashSet(Collection<? extends E> c) {  
  33.         map = new HashMap<E, Object>(Math.max((int) (c.size() / .75f) + 116));  
  34.         addAll(c);  
  35.     }  
  36.   
  37.     /** 
  38.      * 以指定初始容量和加载因子构造HashMap 
  39.      */  
  40.     public HashSet(int initialCapacity, float loadFactor) {  
  41.         map = new HashMap<E, Object>(initialCapacity, loadFactor);  
  42.     }  
  43.   
  44.     /** 
  45.      * 以初始容量构造HashMap 
  46.      */  
  47.     public HashSet(int initialCapacity) {  
  48.         map = new HashMap<E, Object>(initialCapacity);  
  49.     }  
  50.   
  51.     /** 
  52.      *  
  53.      * 构造一个Linked hash set. 
  54.      * 以指定初始容量,加载因子构造LinkedHashMap,dummy只是为了区别其他构造方法 
  55.      *  
  56.      */  
  57.     HashSet(int initialCapacity, float loadFactor, boolean dummy) {  
  58.         map = new LinkedHashMap<E, Object>(initialCapacity, loadFactor);  
  59.     }  
  60.   
  61.     /** 
  62.      * 获得HashMap的键集迭代器 
  63.      */  
  64.     public Iterator<E> iterator() {  
  65.         return map.keySet().iterator();  
  66.     }  
  67.   
  68.     /** 
  69.      * 返回元素个数 
  70.      */  
  71.     public int size() {  
  72.         return map.size();  
  73.     }  
  74.   
  75.     /** 
  76.      * 判断Hash集是否为空 
  77.      */  
  78.     public boolean isEmpty() {  
  79.         return map.isEmpty();  
  80.     }  
  81.   
  82.     /** 
  83.      * 如果Map中含有此key则返回true 
  84.      */  
  85.     public boolean contains(Object o) {  
  86.         return map.containsKey(o);  
  87.     }  
  88.   
  89.     /** 
  90.      *  
  91.      * 如果e不存在于Set中则添加e到集合, 
  92.      * 如果Map中key集不存在e,则添加并返回null,否则替换原来的value,返回oldValue 
  93.      * 
  94.      */  
  95.     public boolean add(E e) {  
  96.         return map.put(e, PRESENT) == null;  
  97.     }  
  98.   
  99.     /** 
  100.      * 移除指定元素 
  101.      */  
  102.     public boolean remove(Object o) {  
  103.         return map.remove(o) == PRESENT;  
  104.     }  
  105.   
  106.     /** 
  107.      * 清空map 
  108.      */  
  109.     public void clear() {  
  110.         map.clear();  
  111.     }  
  112.   
  113.     /** 
  114.      * 返回HashSet的浅拷贝对象 
  115.      */  
  116.     public Object clone() {  
  117.         try {  
  118.             HashSet<E> newSet = (HashSet<E>) super.clone();  
  119.             newSet.map = (HashMap<E, Object>) map.clone();      
  120.             return newSet;  
  121.         } catch (CloneNotSupportedException e) {  
  122.             throw new InternalError();  
  123.         }  
  124.     }  
  125.   
  126.   
  127.     private void writeObject(java.io.ObjectOutputStream s)  
  128.             throws java.io.IOException {  
  129.         // Write out any hidden serialization magic  
  130.         s.defaultWriteObject();  
  131.   
  132.         //写入HashMap的容量和加载系数  
  133.         s.writeInt(map.capacity());  
  134.         s.writeFloat(map.loadFactor());  
  135.   
  136.         //写入size  
  137.         s.writeInt(map.size());  
  138.   
  139.         //依次写入键值  
  140.         for (Iterator i = map.keySet().iterator(); i.hasNext();)  
  141.             s.writeObject(i.next());  
  142.     }  
  143.   
  144.   
  145.     private void readObject(java.io.ObjectInputStream s)  
  146.             throws java.io.IOException, ClassNotFoundException {  
  147.         // Read in any hidden serialization magic  
  148.         s.defaultReadObject();  
  149.   
  150.         //读取容量和加载因子构造HashMap  
  151.         int capacity = s.readInt();  
  152.         float loadFactor = s.readFloat();  
  153.         //判断是LinkedHashMap还是HashMap  
  154.         map = (((HashSet) thisinstanceof LinkedHashSet ? new LinkedHashMap<E, Object>(  
  155.                 capacity, loadFactor)  
  156.                 : new HashMap<E, Object>(capacity, loadFactor));  
  157.   
  158.         // 读size  
  159.         int size = s.readInt();  
  160.   
  161.         //依次读出所有元素  
  162.         for (int i = 0; i < size; i++) {  
  163.             E e = (E) s.readObject();  
  164.             map.put(e, PRESENT);  
  165.         }  
  166.     }  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值