Java ArrayList的類比實現

來源:互聯網
上載者:User

標籤:固定   java數組   collect   exception   插入   myarray   lis   color   range   

package test;import java.util.Arrays;import java.util.Collection;public class MyArrayList<E> {        //儲存資料    private Object[] values;        //已經使用的容量    private int size;        //修改次數    private int modCount;        /**     * 根據給定容量初始化     * @param initialCapacity     */    public MyArrayList(int initialCapacity){        if(initialCapacity > 0){//按照給定的容量大小初始化數組            values = new Object[initialCapacity];        }else if(initialCapacity == 0){            values = new Object[]{};        }else{            throw new IllegalArgumentException("非法初始化容量: "+                    initialCapacity);        }    }        /**     * 預設初始化方法     */    public MyArrayList(){        this(10);    }        /**     * 用集合初始化一個ArrayList     * @param c     */    public MyArrayList(Collection c){        values = c.toArray();        if (values.length != 0) {            size = values.length;            if (values.getClass() != Object[].class)                values = Arrays.copyOf(values, size, Object[].class);        }else{            values = new Object[]{};        }    }    /**     * 檢查是否數組越界了     * @param index     */    private void rangeCheck(int index) {        if (index >= size || index < 0)            throw new IndexOutOfBoundsException("數組越界了");    }        /**     * 替換原數組中的值,並且將原值返回     * @param index     * @param element     * @return     */    public E set(int index,E element){        //檢查是否越界        rangeCheck(index);                E oldValue = (E)values[index];        values[index] = element;                return oldValue;    }        /**     * 在數組的末尾增加一個元素     * @param element     */    public void add(E element){        //擴容        ensureCapacity(size+1);        values[size++] = element;            }        /**     * @param index     * @param element     */    public void add(int index,E element){        //先檢查數組的下標是否越界了        rangeCheck(index);        //擴容        ensureCapacity(size+1);                Object[] oldValues = values;        values[index] = element;                //將原數組index後的值拷貝帶新數組中        System.arraycopy(oldValues, index, values, index+1, size-index);                size++;            }        /**     * 將一個collection中的元素添加到數組末尾     * @param c     */    public void addAll(Collection c){        Object[] cArray = c.toArray();                //擴容        ensureCapacity(size+cArray.length);                //將傳入資料拷貝到數組末尾        System.arraycopy(cArray, 0, values, size, cArray.length);                size += cArray.length;    }        /**     * 將一個collection中的元素添加到數組的指定位置     * @param index     * @param c     */    public void addAll(int index,Collection c){        //先檢查數組的下標是否越界了        rangeCheck(index);        //擴容        Object[] cArray = c.toArray();        int cLength = cArray.length;                ensureCapacity(size+cLength);                Object[] oldValues = values;        //將傳入資料拷貝到數組指定位置        System.arraycopy(cArray, 0, values, index, cLength);                //將原數組中index以後的資料拷貝過來        System.arraycopy(oldValues, index, values, values.length-1, size-index);                size += cLength;            }        /**     * 根據下標擷取元素     * @param index     * @return     */    public E get(int index){        //先檢查數組的下標是否越界了        rangeCheck(index);                E e = (E) values[index];                return e;            }        /**     * 根據下標刪除元素     * @param index     * @return     */    public E remove(int index){        //先檢查數組的下標是否越界了        rangeCheck(index);                E removeValue = (E) values[index];                System.arraycopy(values, index+1, values, index, size-index-1);                //置為空白,gc回收        values[size--] = null;                return removeValue;            }        /**     * 根據對象刪除     * @param o     */    public void remove(Object o){        //考慮元素為null的情況        if(null == o){            for (int i = 0; i < size; i++) {                if(values[i] == null){                    remove(i);                }            }                    }else{            for (int i = 0; i < size; i++) {                if(values[i].equals(o)){                    remove(i);                }            }                    }    }        /**     * 擴容方法,保證數組的長度足夠     * @param minCapacity     */    public void ensureCapacity(int minCapacity){        modCount++;                int oldCapacity = values.length;        if (minCapacity > oldCapacity) {            //先預設擴容50%+1,如果還是不能滿足,則直接用傳入的所需容量            int newCapacity = (oldCapacity*3)/2+1;            if(newCapacity < minCapacity){                newCapacity = minCapacity;            }                        values = Arrays.copyOf(values, newCapacity);                    }    }        public int size(){        return size;    }    }

最後再介紹一下ensureCapacity這個方法的想法(從網上看到的):

我們知道ArrayList的內部是採用數組來儲存元素的,由於java數組都是定長的,所以這個數組的大小一定是固定的,這個大小就是capacity。我們可以肯定capacity一定是大於或等於ArrayList的size,那麼當size不斷增加到了要超過capacity的時候,ArrayList就不得不重新建立新的capacity來容納更多的元素,這時需要首先建立一個更長的數組,將原來的數組中的元素複製到新數組中,再刪除原來的數組。可見當ArrayList越來越大時,這種操作的消耗也是越來越大的。
為了減少這種不必要的重建capacity的操作,當我們能肯定ArrayList大致有多大(或者至少會有多大)時,我們可以先讓ArrayList把capacity設為我們期望的大小,以避免多餘的數組重建。
假設ArrayList自動把capacity設為10,每次重建時將長度遞增原來的三分之二,那麼當我們需要大約儲存50個元素到ArrayList中時,就會大約需要重建數組4次,分別是在增加第11、第17、第26、第39個元素的時候進行的。如果我們一開始就讓ArrayList的capacity為50,那麼不需要任何數組重建就能完成所有插入操作了。
java允許我們在構造ArrayList的同時指定capacity,如new ArrayList(50),也允許在以後將它設得更大,而增大capacity就是使用ensureCapacity()方法。注意:capacity只能比原來的更大,而不能比原來的更小,否則java會忽略該操作。ArrayList的初始預設capacity為10,所以給capacity指定小於10的整數是毫無意義的。
最後說說ArrayList的size,前面說過,size一定小於等於capactiy,而且更重要的是,訪問超過size的位置將拋出異常,儘管這個位置可能沒有超過capacity。ensureCapacity()只可能增加capacity,而不會對size有任何影響。要增加size,只能用add()方法。

Java ArrayList的類比實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.