1. 程式人生 > >自己寫一個簡單的ArrayList

自己寫一個簡單的ArrayList

自己通過寫一個簡單的SimpleArrayList來加深對JDK原始碼中的ArrayList的理解。

  • 構造器
    如果沒有對集合設定長度,這裡我們預設採取長度為10作為內建陣列的初始化長度。
    public SimpleArrayList() {
        this(DEFAULT_SIZE);
    }
    public SimpleArrayList(int size) {
        target = new Object[size];
    }
  • 向集合中新增元素add(E)
    這裡用到了Arrays類的copyof。如果長度超過我們設定的長度。陣列中的元素複製到新陣列。新陣列長度為原陣列的2倍。(當然這裡可以自定義設定擴容比例)
    由於陣列長度設定不能大於int的長度即java.lang.Integer.MAX_VALUE = 2^31-1 = 2147483647(實際上虛擬機器記憶體不一定支援理論上的最大值),這裡沒有加上這個校驗,真實的程式是有這個校驗的。
    public void add(E e){
        if(this.size < DEFAULT_SIZE){
            //小於預設尺寸10
            target[size++] = e;
        }else{
            //大於10的時候需要擴容,
            //copyOf複製指定的陣列到新陣列,第一個引數為原陣列,第二個引數為新陣列長度
            target = Arrays.copyOf(target, size*2);
            target[size++] = e;
        }
    }
  • 根據下標獲取元素get(index)
    public E get(int index){
        return (E)target[index];
    }
  • 返回集合長度size()方法
    public int size(){
        return this.size;
    }
  • 判斷元素是否在集合 indexOf(Object)
    public int indexOf(Object obj){
        if(obj==null){
            for(int i=0;i<target.length;i++){
                if
(target[i]==null){ return i; } } }else{ for(int i=0;i<target.length;i++){ if(obj.equals(target[i])){ return i; } } } return -1; }
  • 根據下標移除集合中的元素remove(index)
    System.arraycopy(被複制的陣列,被複制位置,目標陣列,目標陣列位置,被複制陣列的結束到開始的長度)
    target將index+1到最後的所有資料,複製到target的排除e元素即index位置到最後的位置。
    這樣的陣列長度還是沒有變化的,所以,–size,讓集合長度減一,而溢位的這個元素,等待GC回收
    public E remove(int index){
        E e =get(index);
        System.arraycopy(target, index+1, target, index, size-index-1);
        target[--size] = null;
        return e;
    }
  • 根據元素移除集合中和該元素相同的元素remove(Object)
    public boolean remove(Object o){
        if(o==null){
            for(int i=0;i<target.length;i++){
                if(target[i]==null){
                    remove(i);
                    return true;
                }
            }
        }else{
            for(int i=0;i<target.length;i++){
                if(o.equals(target[i])){
                    remove(i);
                    return true;
                }
            }
        }
        return false;
    }
  • 清空集合(clear)
    public void clear(){
        for(int i=0;i<target.length;i++){
            target[i] =null;
        }
        size = 0;
    }

最後附上全部的原始碼,有什麼不對的地方,請指出。

/**
 * 模擬ArrayList
 * 1,實現方法,get(int),add(E),add(int,E),size(),remove(int),remove(Object),indexOf(Object)
 * 2,ArrayList本質上是動態陣列
 * 3,巧用System.arraycopy和Arrays.copyof來實現元素的新增和刪除
 *
 */
public class SimpleArrayList<E> {
    private final static int DEFAULT_SIZE = 10;

    private int size;

    private Object[] target;

    public SimpleArrayList() {
        this(DEFAULT_SIZE);
    }
    public SimpleArrayList(int size) {
        target = new Object[size];
    }

    /**
     * 向集合中新增元素
     * @param e 元素
     */
    public void add(E e){
        if(this.size < DEFAULT_SIZE){
            //小於預設尺寸10
            target[size++] = e;
        }else{
            //大於10的時候需要擴容,
            //copyOf複製指定的陣列到新陣列,第一個引數為原陣列,第二個引數為新陣列長度
            target = Arrays.copyOf(target, size*2);
            target[size++] = e;
        }
    }

    /**
     * 根據下標獲取集合中的元素
     * @param index 下標
     * @return
     */
    public E get(int index){
        return (E)target[index];
    }

    /**
     * 返回集合長度
     * @return
     */
    public int size(){
        return this.size;
    }

    /**
     * 判斷元素是否存在集合中
     * 存在返回下標
     * 不存在返回-1
     * @param obj
     * @return
     */
    public int indexOf(Object obj){
        if(obj==null){
            for(int i=0;i<target.length;i++){
                if(target[i]==null){
                    return i;
                }
            }
        }else{
            for(int i=0;i<target.length;i++){
                if(obj.equals(target[i])){
                    return i;
                }
            }
        }

        return -1;
    }
    /**
     * 根據下標移出集合中的元素
     * @param index 下標
     * @return
     */
    public E remove(int index){
        E e =get(index);
        /**
         * System.arraycopy(被複制的陣列,被複制位置,目標陣列,目標陣列位置,被複制陣列的結束到開始的長度)
         * 
         * target將index+1到最後的所有資料,複製到target的排除e元素即index位置到最後的位置。
         * 
         * 這樣的陣列長度還是沒有變化的,所以,--size,讓集合長度減一,而溢位的這個元素,等待GC回收
         */
        System.arraycopy(target, index+1, target, index, size-index-1);
        target[--size] = null;
        return e;
    }
    /**
     * 根據移除集合中的元素
     * 移除成功返回true,反之false
     * @param o 元素
     * @return
     */
    public boolean remove(Object o){
        if(o==null){
            for(int i=0;i<target.length;i++){
                if(target[i]==null){
                    remove(i);
                    return true;
                }
            }
        }else{
            for(int i=0;i<target.length;i++){
                if(o.equals(target[i])){
                    remove(i);
                    return true;
                }
            }
        }
        return false;
    }
    /**
     * 清空集合
     */
    public void clear(){
        for(int i=0;i<target.length;i++){
            target[i] =null;
        }
        size = 0;
    }


}