自己写一个简单的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;iif(target[i]==null){
                    return i;
                }
            }
        }else{
            for(int i=0;iif(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;iif(target[i]==null){
                    remove(i);
                    return true;
                }
            }
        }else{
            for(int i=0;iif(o.equals(target[i])){
                    remove(i);
                    return true;
                }
            }
        }
        return false;
    }
  • 清空集合(clear)
    public void clear(){
        for(int i=0;inull;
        }
        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;iif(target[i]==null){
                    return i;
                }
            }
        }else{
            for(int i=0;iif(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;iif(target[i]==null){
                    remove(i);
                    return true;
                }
            }
        }else{
            for(int i=0;iif(o.equals(target[i])){
                    remove(i);
                    return true;
                }
            }
        }
        return false;
    }
    /**
     * 清空集合
     */
    public void clear(){
        for(int i=0;inull;
        }
        size = 0;
    }


}

你可能感兴趣的:(java基础)