Java重要類詳解之ArrayList類


 

https://blog.csdn.net/shengmingqijiquan/article/details/52634640

 

一.ArrayList概述

  • ArrayList 是一個數組隊列,相當於動態數組。與Java中的數組相比,它的容量能動態增長。它繼承於AbstractList,實現了List,RandomAccess[隨機訪問],Cloneable[可克隆], java.io.Serializable[序列化]這些接口。
  • ArrayList 繼承了AbstractList,實現了List。它是一個數組隊列,提供了相關的添加、刪除、修改、遍歷等功能。
  • ArrayList 實現了RandmoAccess接口,即提供了隨機訪問功能。RandmoAccess是java中用來被List實現,為List提供快速訪問功能的。在ArrayList中,我們即可以通過元素的序號快速獲取元素對象;這就是快速隨機訪問。稍后,我們會比較List的“快速隨機訪問”和“通過Iterator迭代器訪問”的效率。
  • ArrayList 實現了Cloneable接口,即覆蓋了函數clone(),能被克隆。
  • ArrayList 實現java.io.Serializable接口,這意味着ArrayList支持序列化,能通過序列化去傳輸。
  • 和Vector不同,ArrayList中的操作不是線程安全的。所以,建議在單線程中才使用ArrayList,而在多線程中可以選擇Vector或者CopyOnWriteArrayList。
PS:以上繼承關系可以表示為以下形式:

 

二.ArrayList之API  

 

1.ArrayList和Collection之間的關系

*實線代表直接繼承的父類,虛線代表實現的接口;

2.ArrayList類的API

  1.  
    <span style= "font-family:Microsoft YaHei;">// Collection中定義的API
  2.  
    boolean             add(E object)//添加一個數組對象
  3.  
    boolean             addAll(Collection<? extends E> collection)//添加一個包含Collection的對象
  4.  
    void              clear()//清空
  5.  
    boolean             contains(Object object)//包含
  6.  
    boolean             containsAll(Collection<?> collection)
  7.  
    boolean             equals(Object object)//判等
  8.  
    int               hashCode()
  9.  
    boolean             isEmpty()//判空
  10.  
    Iterator<E>         iterator()
  11.  
    boolean             remove(Object object)//刪除
  12.  
    boolean             removeAll(Collection<?> collection)
  13.  
    boolean             retainAll(Collection<?> collection)
  14.  
    int               size()
  15.  
    <T> T[]             toArray(T[] array)
  16.  
    Object[]            toArray()
  17.  
    // AbstractCollection中定義的API
  18.  
    void              add(int location, E object)
  19.  
    boolean             addAll(int location, Collection<? extends E> collection)
  20.  
    E                get(int location)//獲取某個元素值
  21.  
    int               indexOf(Object object)
  22.  
    int               lastIndexOf(Object object)
  23.  
    ListIterator<E>     listIterator(int location)
  24.  
    ListIterator<E>     listIterator()
  25.  
    E                remove(int location)
  26.  
    E                set(int location, E object)
  27.  
    List<E>             subList(int start, int end)
  28.  
    // ArrayList新增的API
  29.  
    Object              clone()//
  30.  
    void              ensureCapacity(int minimumCapacity)//保證容量不小於元素個數
  31.  
    void              trimToSize()
  32.  
    void              removeRange(int fromIndex, int toIndex)
  33.  
    </span>

3.ArrayList的源碼解析

  1.  
    <span style= "font-family:Microsoft YaHei;">package java.util;
  2.  
    public class ArrayList<E> extends AbstractList<E>
  3.  
            implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  4.  
    {
  5.  
        // 序列版本號
  6.  
        private static final long serialVersionUID = 8683452581122892189L;
  7.  
        // 保存ArrayList中數據的數組
  8.  
        private transient Object[] elementData;
  9.  
        // ArrayList中實際數據的數量
  10.  
        private int size;
  11.  
        // ArrayList帶容量大小的構造函數。
  12.  
        public ArrayList(int initialCapacity) {
  13.  
            super();
  14.  
            if (initialCapacity < 0)
  15.  
                throw new IllegalArgumentException("Illegal Capacity: "+
  16.  
                                                   initialCapacity);
  17.  
            // 新建一個數組
  18.  
            this.elementData = new Object[initialCapacity];
  19.  
        }
  20.  
        // ArrayList構造函數。默認容量是10。
  21.  
        public ArrayList() {
  22.  
            this(10);
  23.  
        }
  24.  
        // 創建一個包含collection的ArrayList
  25.  
        public ArrayList(Collection<? extends E> c) {
  26.  
            elementData = c.toArray();
  27.  
            size = elementData.length;
  28.  
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
  29.  
            if (elementData.getClass() != Object[].class)
  30.  
                elementData = Arrays.copyOf(elementData, size, Object[].class);
  31.  
        }
  32.  
        // 將當前容量值設為 =實際元素個數
  33.  
        public void trimToSize() {
  34.  
            modCount++;
  35.  
            int oldCapacity = elementData.length;
  36.  
            if (size < oldCapacity) {
  37.  
                elementData = Arrays.copyOf(elementData, size);
  38.  
            }
  39.  
        }
  40.  
        // 確定ArrarList的容量。
  41.  
        // 若ArrayList的容量不足以容納當前的全部元素,設置 新的容量=“(原始容量x3)/2 + 1”
  42.  
        public void ensureCapacity(int minCapacity) {
  43.  
            // 將“修改統計數”+1
  44.  
            modCount++;
  45.  
            int oldCapacity = elementData.length;
  46.  
            // 若當前容量不足以容納當前的元素個數,設置 新的容量=“(原始容量x3)/2 + 1”
  47.  
            if (minCapacity > oldCapacity) {
  48.  
                Object oldData[] = elementData;
  49.  
                int newCapacity = (oldCapacity * 3)/2 + 1;
  50.  
                if (newCapacity < minCapacity)
  51.  
                    newCapacity = minCapacity;
  52.  
                elementData = Arrays.copyOf(elementData, newCapacity);
  53.  
            }
  54.  
        }
  55.  
        // 添加元素e
  56.  
        public boolean add(E e) {
  57.  
            // 確定ArrayList的容量大小
  58.  
            ensureCapacity(size + 1);  // Increments modCount!!
  59.  
            // 添加e到ArrayList中
  60.  
            elementData[size++] = e;
  61.  
            return true;
  62.  
        }
  63.  
        // 返回ArrayList的實際大小
  64.  
        public int size() {
  65.  
            return size;
  66.  
        }
  67.  
        // 返回ArrayList是否包含Object(o)
  68.  
        public boolean contains(Object o) {
  69.  
            return indexOf(o) >= 0;
  70.  
        }
  71.  
        // 返回ArrayList是否為空
  72.  
        public boolean isEmpty() {
  73.  
            return size == 0;
  74.  
        }
  75.  
        // 正向查找,返回元素的索引值
  76.  
        public int indexOf(Object o) {
  77.  
            if (o == null) {
  78.  
                for (int i = 0; i < size; i++)
  79.  
                if (elementData[i]==null)
  80.  
                    return i;
  81.  
                } else {
  82.  
                    for (int i = 0; i < size; i++)
  83.  
                    if (o.equals(elementData[i]))
  84.  
                        return i;
  85.  
                }
  86.  
                return -1;
  87.  
            }
  88.  
            // 反向查找,返回元素的索引值
  89.  
            public int lastIndexOf(Object o) {
  90.  
            if (o == null) {
  91.  
                for (int i = size-1; i >= 0; i--)
  92.  
                if (elementData[i]==null)
  93.  
                    return i;
  94.  
            } else {
  95.  
                for (int i = size-1; i >= 0; i--)
  96.  
                if (o.equals(elementData[i]))
  97.  
                    return i;
  98.  
            }
  99.  
            return -1;
  100.  
        }
  101.  
        // 反向查找(從數組末尾向開始查找),返回元素(o)的索引值
  102.  
        public int lastIndexOf(Object o) {
  103.  
            if (o == null) {
  104.  
                for (int i = size-1; i >= 0; i--)
  105.  
                if (elementData[i]==null)
  106.  
                    return i;
  107.  
            } else {
  108.  
                for (int i = size-1; i >= 0; i--)
  109.  
                if (o.equals(elementData[i]))
  110.  
                    return i;
  111.  
            }
  112.  
            return -1;
  113.  
        }
  114.  
     
  115.  
        // 返回ArrayList的Object數組
  116.  
        public Object[] toArray() {
  117.  
            return Arrays.copyOf(elementData, size);
  118.  
        }
  119.  
        // 返回ArrayList的模板數組。所謂模板數組,即可以將T設為任意的數據類型
  120.  
        public <T> T[] toArray(T[] a) {
  121.  
            // 若數組a的大小 < ArrayList的元素個數;
  122.  
            // 則新建一個T[]數組,數組大小是“ArrayList的元素個數”,並將“ArrayList”全部拷貝到新數組中
  123.  
            if (a.length < size)
  124.  
                return (T[]) Arrays.copyOf(elementData, size, a.getClass());
  125.  
            // 若數組a的大小 >= ArrayList的元素個數;
  126.  
            // 則將ArrayList的全部元素都拷貝到數組a中。
  127.  
            System.arraycopy(elementData, 0, a, 0, size);
  128.  
            if (a.length > size)
  129.  
                a[size] = null;
  130.  
            return a;
  131.  
        }
  132.  
        // 獲取index位置的元素值
  133.  
        public E get(int index) {
  134.  
            RangeCheck(index);
  135.  
            return (E) elementData[index];
  136.  
        }
  137.  
        // 設置index位置的值為element
  138.  
        public E set(int index, E element) {
  139.  
            RangeCheck(index);
  140.  
            E oldValue = (E) elementData[index];
  141.  
            elementData[index] = element;
  142.  
            return oldValue;
  143.  
        }
  144.  
        // 將e添加到ArrayList中
  145.  
        public boolean add(E e) {
  146.  
            ensureCapacity(size + 1);  // Increments modCount!!
  147.  
            elementData[size++] = e;
  148.  
            return true;
  149.  
        }
  150.  
        // 將e添加到ArrayList的指定位置
  151.  
        public void add(int index, E element) {
  152.  
            if (index > size || index < 0)
  153.  
                throw new IndexOutOfBoundsException(
  154.  
                "Index: "+index+", Size: "+size);
  155.  
            ensureCapacity(size+ 1);  // Increments modCount!!
  156.  
            System.arraycopy(elementData, index, elementData, index + 1,
  157.  
                 size - index);
  158.  
            elementData[index] = element;
  159.  
            size++;
  160.  
        }
  161.  
        // 刪除ArrayList指定位置的元素
  162.  
        public E remove(int index) {
  163.  
            RangeCheck(index);
  164.  
            modCount++;
  165.  
            E oldValue = (E) elementData[index];
  166.  
            int numMoved = size - index - 1;
  167.  
            if (numMoved > 0)
  168.  
                System.arraycopy(elementData, index+ 1, elementData, index,
  169.  
                     numMoved);
  170.  
            elementData[--size] = null; // Let gc do its work
  171.  
            return oldValue;
  172.  
        }
  173.  
        // 刪除ArrayList的指定元素
  174.  
        public boolean remove(Object o) {
  175.  
            if (o == null) {
  176.  
                    for (int index = 0; index < size; index++)
  177.  
                if (elementData[index] == null) {
  178.  
                    fastRemove(index);
  179.  
                    return true;
  180.  
                }
  181.  
            } else {
  182.  
                for (int index = 0; index < size; index++)
  183.  
                if (o.equals(elementData[index])) {
  184.  
                    fastRemove(index);
  185.  
                    return true;
  186.  
                }
  187.  
            }
  188.  
            return false;
  189.  
        }
  190.  
        // 快速刪除第index個元素
  191.  
        private void fastRemove(int index) {
  192.  
            modCount++;
  193.  
            int numMoved = size - index - 1;
  194.  
            // 從"index+1"開始,用后面的元素替換前面的元素。
  195.  
            if (numMoved > 0)
  196.  
                System.arraycopy(elementData, index+ 1, elementData, index,
  197.  
                                 numMoved);
  198.  
            // 將最后一個元素設為null
  199.  
            elementData[--size] = null; // Let gc do its work
  200.  
        }
  201.  
        // 刪除元素
  202.  
        public boolean remove(Object o) {
  203.  
            if (o == null) {
  204.  
                for (int index = 0; index < size; index++)
  205.  
                if (elementData[index] == null) {
  206.  
                    fastRemove(index);
  207.  
                return true;
  208.  
                }
  209.  
            } else {
  210.  
                // 便利ArrayList,找到“元素o”,則刪除,並返回true。
  211.  
                for (int index = 0; index < size; index++)
  212.  
                if (o.equals(elementData[index])) {
  213.  
                    fastRemove(index);
  214.  
                return true;
  215.  
                }
  216.  
            }
  217.  
            return false;
  218.  
        }
  219.  
        // 清空ArrayList,將全部的元素設為null
  220.  
        public void clear() {
  221.  
            modCount++;
  222.  
            for (int i = 0; i < size; i++)
  223.  
                elementData[i] = null;
  224.  
            size = 0;
  225.  
        }
  226.  
        // 將集合c追加到ArrayList中
  227.  
        public boolean addAll(Collection<? extends E> c) {
  228.  
            Object[] a = c.toArray();
  229.  
            int numNew = a.length;
  230.  
            ensureCapacity(size + numNew);  // Increments modCount
  231.  
            System.arraycopy(a, 0, elementData, size, numNew);
  232.  
            size += numNew;
  233.  
            return numNew != 0;
  234.  
        }
  235.  
        // 從index位置開始,將集合c添加到ArrayList
  236.  
        public boolean addAll(int index, Collection<? extends E> c) {
  237.  
            if (index > size || index < 0)
  238.  
                throw new IndexOutOfBoundsException(
  239.  
                "Index: " + index + ", Size: " + size);
  240.  
            Object[] a = c.toArray();
  241.  
            int numNew = a.length;
  242.  
            ensureCapacity(size + numNew);  // Increments modCount
  243.  
            int numMoved = size - index;
  244.  
            if (numMoved > 0)
  245.  
                System.arraycopy(elementData, index, elementData, index + numNew,
  246.  
                     numMoved);
  247.  
            System.arraycopy(a, 0, elementData, index, numNew);
  248.  
            size += numNew;
  249.  
            return numNew != 0;
  250.  
        }
  251.  
        // 刪除fromIndex到toIndex之間的全部元素。
  252.  
        protected void removeRange(int fromIndex, int toIndex) {
  253.  
        modCount++;
  254.  
        int numMoved = size - toIndex;
  255.  
            System.arraycopy(elementData, toIndex, elementData, fromIndex,
  256.  
                             numMoved);
  257.  
        // Let gc do its work
  258.  
        int newSize = size - (toIndex-fromIndex);
  259.  
        while (size != newSize)
  260.  
            elementData[--size] = null;
  261.  
        }
  262.  
        private void RangeCheck(int index) {
  263.  
        if (index >= size)
  264.  
            throw new IndexOutOfBoundsException(
  265.  
            "Index: "+index+", Size: "+size);
  266.  
        }
  267.  
        // 克隆函數
  268.  
        public Object clone() {
  269.  
            try {
  270.  
                ArrayList<E> v = (ArrayList<E>) super.clone();
  271.  
                // 將當前ArrayList的全部元素拷貝到v中
  272.  
                v.elementData = Arrays.copyOf(elementData, size);
  273.  
                v.modCount = 0;
  274.  
                return v;
  275.  
            } catch (CloneNotSupportedException e) {
  276.  
                // this shouldn't happen, since we are Cloneable
  277.  
                throw new InternalError();
  278.  
            }
  279.  
        }
  280.  
        // java.io.Serializable的寫入函數
  281.  
        // 將ArrayList的“容量,所有的元素值”都寫入到輸出流中
  282.  
        private void writeObject(java.io.ObjectOutputStream s)
  283.  
            throws java.io.IOException{
  284.  
        // Write out element count, and any hidden stuff
  285.  
        int expectedModCount = modCount;
  286.  
        s.defaultWriteObject();
  287.  
            // 寫入“數組的容量”
  288.  
            s.writeInt(elementData.length);
  289.  
        // 寫入“數組的每一個元素”
  290.  
        for (int i=0; i<size; i++)
  291.  
                s.writeObject(elementData[i]);
  292.  
        if (modCount != expectedModCount) {
  293.  
                throw new ConcurrentModificationException();
  294.  
            }
  295.  
        }
  296.  
        // java.io.Serializable的讀取函數:根據寫入方式讀出
  297.  
        // 先將ArrayList的“容量”讀出,然后將“所有的元素值”讀出
  298.  
        private void readObject(java.io.ObjectInputStream s)
  299.  
            throws java.io.IOException, ClassNotFoundException {
  300.  
            // Read in size, and any hidden stuff
  301.  
            s.defaultReadObject();
  302.  
            // 從輸入流中讀取ArrayList的“容量”
  303.  
            int arrayLength = s.readInt();
  304.  
            Object[] a = elementData = new Object[arrayLength];
  305.  
            // 從輸入流中將“所有的元素值”讀出
  306.  
            for (int i=0; i<size; i++)
  307.  
                a[i] = s.readObject();
  308.  
        }
  309.  
    }
  310.  
    </span>
 

重點總結:

  • ArrayList 實際上是通過一個數組去保存數據的。當我們構造ArrayList時;若使用默認構造函數,則ArrayList的默認容量大小是10。
  • 當ArrayList容量不足以容納全部元素時,ArrayList會重新設置容量:新的容量=“(原始容量x3)/2 + 1”。
  • ArrayList的克隆函數,即是將全部元素克隆到一個數組中。
  • ArrayList實現java.io.Serializable的方式。當寫入到輸出流時,先寫入“容量”,再依次寫入“每一個元素”;當讀出輸入流時,先讀取“容量”,再依次讀取“每一個元素”。

三.ArrayList的使用實例

1.ArrayList的添加

將字符a添加到list當中

 

  1.  
    <span style= "font-family:Microsoft YaHei;">package com.ArrayList;
  2.  
     
  3.  
    import java.util.ArrayList;
  4.  
     
  5.  
    /**
  6.  
    * @author shengmingqijiquan
  7.  
    * @since 2016.09.23
  8.  
    *
  9.  
    * */
  10.  
    public class MyArrayList{
  11.  
    public static void main(String[] args) {
  12.  
    ArrayList<String> list = new ArrayList<String>();
  13.  
    list.add( "a");//按照順序依次添加。將a添加到list中
  14.  
    System.out.println(list+ " ");
  15.  
    list.add( 1,"b");//在第1個元素后面添加E,ArrayList中必須有足夠多的數據,例如ArrayList中沒有任何數據,這個時候使用arraylist.add(1, "E");就會出現java.lang.IndexOutOfBoundsException異常。
  16.  
    System.out.println(list+ " ");
  17.  
    ArrayList<String> list1 = new ArrayList<String>();
  18.  
    list1.addAll(list); //將list中的全部數據添加到list1中
  19.  
    System.out.println(list1+ " ");
  20.  
    list1.addAll( 1,list);//將一個ArrayList中的所有數據添加到另外一個ArraList中的第1個元素之后
  21.  
    System.out.println(list1+ " ");
  22.  
     
  23.  
    }
  24.  
     
  25.  
    }
  26.  
    </span>

運行結果:

 

2.ArrayList的刪除

  1.  
    <span style= "font-family:Microsoft YaHei;">package com.ArrayList;
  2.  
     
  3.  
    import java.util.ArrayList;
  4.  
    /**
  5.  
    * @author shengmingqijiquan
  6.  
    * @since 2016.09.23
  7.  
    *
  8.  
    * */
  9.  
    public class ArrrayListRemove {
  10.  
    public static void main(String[] args) {
  11.  
    ArrayList<String> list = new ArrayList<String>();
  12.  
    list.add( "a");
  13.  
    list.add( "b");
  14.  
    list.add( "c");
  15.  
    list.add( "d");
  16.  
    list.add( "e");
  17.  
    System.out.println(list+ " ");
  18.  
     
  19.  
    //1.按照內容刪除單個數據.注意:對於int,String,char這樣的原始類型數據是可以刪除的,但是對於復雜對象,例如自己編寫的User類、Person類對象,需要重寫equals方法,負責remove方法無法匹配刪除。
  20.  
    list.remove( "a");//將list中的數據"d"刪除
  21.  
    System.out.println( "刪除單個數據a:"+list);
  22.  
     
  23.  
    //2.按照集合同時刪除多個數據
  24.  
    ArrayList<String> list1 = new ArrayList<String>();
  25.  
    list1.add( "a");
  26.  
    list1.add( "b");
  27.  
    list.removeAll(list1); //按照list1的數據刪除list
  28.  
    System.out.println( "刪除多個數據后,清空之前 "+list);
  29.  
     
  30.  
    //3.清空ArrayList
  31.  
    list.clear();
  32.  
    System.out.println( "清空之后 "+list);
  33.  
     
  34.  
    }
  35.  
    }
  36.  
    </span>
運行結果:
 

3.ArrayList的修改

  1.  
    <span style= "font-family:Microsoft YaHei;">package com.ArrayList;
  2.  
     
  3.  
    import java.util.ArrayList;
  4.  
    /**
  5.  
    * @author shengmingqijiquan
  6.  
    * @date 2016.09.23
  7.  
    * */
  8.  
    public class ArrayListSet {
  9.  
     
  10.  
    public static void main(String[] args) {
  11.  
    ArrayList<String> list = new ArrayList<>();
  12.  
    list.add( "a");
  13.  
    list.add( "b");
  14.  
    list.add( "c");
  15.  
    list.add( "d");
  16.  
    list.add( "e");
  17.  
    System.out.println( "修改前"+list);
  18.  
    list.set( 1,"f");
  19.  
    list.set( 2,"g");
  20.  
    System.out.println( "修改后"+list);
  21.  
    }
  22.  
     
  23.  
    }
  24.  
    </span>
運行結果:
 

4.ArrayList的查詢

  1.  
    <span style= "font-family:Microsoft YaHei;">package com.ArrayList;
  2.  
     
  3.  
    import java.util.ArrayList;
  4.  
    /**
  5.  
    * @author shengmingqijiquan
  6.  
    * @date 2016.09.23
  7.  
    * */
  8.  
    public class ArrayListGet {
  9.  
     
  10.  
    public static void main(String[] args) {
  11.  
    ArrayList<String> list = new ArrayList<>();
  12.  
    list.add( "a");
  13.  
    list.add( "b");
  14.  
    list.add( "c");
  15.  
    list.add( "d");
  16.  
    list.add( "e");
  17.  
    System.out.println( "初始化數組:"+list);
  18.  
    String ele = list.get( 1);
  19.  
    System.out.println( "查詢到的元素ele:"+ele);
  20.  
     
  21.  
    }
  22.  
     
  23.  
    }
  24.  
    </span>
運行結果:
 

5.ArrayList的遍歷

ArrayList支持3種遍歷方式

  • 第一種,通過迭代器遍歷。即通過Iterator去遍歷
  1.  
    <span style= "font-family:Microsoft YaHei;">Integer value = null;
  2.  
    Iterator iter = list.iterator();
  3.  
    while (iter.hasNext()) {
  4.  
        value = (Integer)iter.next();
  5.  
    }
  6.  
    </span>
  • 第二種,隨機訪問,通過索引值去遍歷
  1.  
    <span style= "font-family:Microsoft YaHei;">Integer value = null;
  2.  
    int size = list.size();
  3.  
    for (int i=0; i<size; i++) {
  4.  
        value = (Integer)list.get(i);       
  5.  
    }
  6.  
    </span>
  • 第三種,for循環遍歷
  1.  
    <span style= "font-family:Microsoft YaHei;">Integer value = null;
  2.  
    for (Integer integ:list) {
  3.  
    value = integ;
  4.  
    }</span>

比較這三種遍歷方式的效率

  1.  
    <span style= "font-family:Microsoft YaHei;">import java.util.*;
  2.  
    import java.util.concurrent.*;
  3.  
    /*
  4.  
     * @title ArrayList遍歷方式和效率的測試程序。
  5.  
     *
  6.  
     * @author shengmingqijiquan
  7.  
     */
  8.  
    public class ArrayListRandomAccessTest {
  9.  
        public static void main(String[] args) {
  10.  
            List list = new ArrayList();
  11.  
            for (int i=0; i<100000; i++)
  12.  
                list.add(i);
  13.  
            //isRandomAccessSupported(list);
  14.  
            iteratorThroughRandomAccess(list) ;
  15.  
            iteratorThroughIterator(list) ;
  16.  
            iteratorThroughFor2(list) ;
  17.  
     
  18.  
        }
  19.  
        private static void isRandomAccessSupported(List list) {
  20.  
            if (list instanceof RandomAccess) {
  21.  
                System.out.println( "RandomAccess implemented!");
  22.  
            } else {
  23.  
                System.out.println( "RandomAccess not implemented!");
  24.  
            }
  25.  
        }
  26.  
        public static void iteratorThroughRandomAccess(List list) {
  27.  
            long startTime;
  28.  
            long endTime;
  29.  
            startTime = System.currentTimeMillis();
  30.  
            for (int i=0; i<list.size(); i++) {
  31.  
                list.get(i);
  32.  
            }
  33.  
            endTime = System.currentTimeMillis();
  34.  
            long interval = endTime - startTime;
  35.  
            System.out.println( "iteratorThroughRandomAccess:" + interval+" ms");
  36.  
        }
  37.  
        public static void iteratorThroughIterator(List list) {
  38.  
            long startTime;
  39.  
            long endTime;
  40.  
            startTime = System.currentTimeMillis();
  41.  
            for(Iterator iter = list.iterator(); iter.hasNext(); ) {
  42.  
                iter.next();
  43.  
            }
  44.  
            endTime = System.currentTimeMillis();
  45.  
            long interval = endTime - startTime;
  46.  
            System.out.println( "iteratorThroughIterator:" + interval+" ms");
  47.  
        }
  48.  
        public static void iteratorThroughFor2(List list) {
  49.  
            long startTime;
  50.  
            long endTime;
  51.  
            startTime = System.currentTimeMillis();
  52.  
            for(Object obj:list)
  53.  
     
  54.  
            endTime = System.currentTimeMillis();
  55.  
            long interval = endTime - startTime;
  56.  
            System.out.println( "iteratorThroughFor2:" + interval+" ms");
  57.  
        }
  58.  
    }
  59.  
    </span>
運行結果:
iteratorThroughRandomAccess:3 ms
iteratorThroughIterator:8 ms
iteratorThroughFor2:5 ms
由此可見,遍歷ArrayList時,使用隨機訪問(即,通過索引序號訪問)效率最高,而使用迭代器的效率最低!
 

6.ArrayList之toArray()補充

當我們調用ArrayList中的 toArray(),可能遇到過拋出“java.lang.ClassCastException”異常的情況。下面我們說說這是怎么回事。
ArrayList提供了2個toArray()函數:Object[] toArray()<T> T[] toArray(T[] contents)。調用 toArray() 函數會拋出“java.lang.ClassCastException”異常,但是調用 toArray(T[] contents) 能正常返回 T[]。
toArray() 會拋出異常是因為 toArray() 返回的是 Object[] 數組,將 Object[] 轉換為其它類型(如如,將Object[]轉換為的Integer[])則會拋出“java.lang.ClassCastException”異常,因為Java不支持向下轉型。具體的可以參考前面ArrayList.java的源碼介紹部分的toArray()。
解決該問題的辦法是調用 <T> T[] toArray(T[] contents) , 而不是 Object[] toArray()。
調用 toArray(T[] contents) 返回T[]的可以通過以下幾種方式實現。
  1.  
    <span style= "font-family:Microsoft YaHei;">// toArray(T[] contents)調用方式一
  2.  
    public static Integer[] vectorToArray1(ArrayList<Integer> v) {
  3.  
        Integer[] newText = new Integer[v.size()];
  4.  
        v.toArray(newText);
  5.  
        return newText;
  6.  
    }
  7.  
    // toArray(T[] contents)調用方式二。最常用!
  8.  
    public static Integer[] vectorToArray2(ArrayList<Integer> v) {
  9.  
        Integer[] newText = (Integer[])v.toArray( new Integer[0]);
  10.  
        return newText;
  11.  
    }
  12.  
    // toArray(T[] contents)調用方式三
  13.  
    public static Integer[] vectorToArray3(ArrayList<Integer> v) {
  14.  
        Integer[] newText = new Integer[v.size()];
  15.  
        Integer[] newStrings = (Integer[])v.toArray(newText);
  16.  
        return newStrings;
  17.  
    }</span>
 

7.ArrayList綜合實例

import java.util.*;
  1.  
    <span style= "font-family:Microsoft YaHei;">/*
  2.  
     * @title ArrayList常用API的測試程序
  3.  
     * @author shengmingqijiquan
  4.  
     * @email 1127641712@qq.com
  5.  
     */
  6.  
    public class ArrayListTest {
  7.  
        public static void main(String[] args) {
  8.  
     
  9.  
            // 創建ArrayList
  10.  
            ArrayList list = new ArrayList();
  11.  
            // 將“”
  12.  
            list.add( "1");
  13.  
            list.add( "2");
  14.  
            list.add( "3");
  15.  
            list.add( "4");
  16.  
            // 將下面的元素添加到第1個位置
  17.  
            list.add( 0, "5");
  18.  
            // 獲取第1個元素
  19.  
            System.out.println( "the first element is: "+ list.get(0));
  20.  
            // 刪除“3”
  21.  
            list.remove( "3");
  22.  
            // 獲取ArrayList的大小
  23.  
            System.out.println( "Arraylist size=: "+ list.size());
  24.  
            // 判斷list中是否包含"3"
  25.  
            System.out.println( "ArrayList contains 3 is: "+ list.contains(3));
  26.  
            // 設置第2個元素為10
  27.  
            list.set( 1, "10");
  28.  
            // 通過Iterator遍歷ArrayList
  29.  
            for(Iterator iter = list.iterator(); iter.hasNext(); ) {
  30.  
                System.out.println( "next is: "+ iter.next());
  31.  
            }
  32.  
            // 將ArrayList轉換為數組
  33.  
            String[] arr = (String[])list.toArray( new String[0]);
  34.  
            for (String str:arr)
  35.  
                System.out.println( "str: "+ str);
  36.  
            // 清空ArrayList
  37.  
            list.clear();
  38.  
            // 判斷ArrayList是否為空
  39.  
            System.out.println( "ArrayList is empty: "+ list.isEmpty());
  40.  
        }
  41.  
    }
  42.  
    </span>
運行結果:
 
版權聲明:本文為生命奇跡泉原創文章,轉載請注明出處生命奇跡泉http://blog.csdn.net/shengmingqijiquan https://blog.csdn.net/shengmingqijiquan/article/details/52634640


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM