自己实现ArrayList

闲来无事决定模仿jdk实现ArrayList

简述:MyArrayList完全模仿jdk里面的ArrayList,但是没有继承AbstractList,实现了元素的增加、定点增加、删除、定点删除等方法,迭代器还未实现.自己实现的方法自然比不上大神的,但是目的是一样的。

ArrayList的家谱图,里面的方法也显示了,使用idea生成的

ArrayList家谱图

1.代码


/**
*RandomAccess 支持随机访问,毕竟ArrayList是封装数组,该接口表明遍历ArrayList采用for循环比迭代器更快
*Cloneable 克隆接口
*Serializable 序列化接口
*
*/
public class MyArrayList<E> implements List<E>, RandomAccess, Cloneable, Serializable {
	
    private static final long serialVersionUID = 8683452581122892189L;

    /**
     * 默认大小,抄袭ArrayList
     */
    private static final int DEFAULT_CAPACITY = 10;

    /**
     * 数组元素
     */
    transient Object[] elementData; // non-private to simplify nested class access

    /**
     * 数组大小
     */
    private int size;

    /**
     * 无参构造,默认大小为10,还准备了
     */
    public MyArrayList(){
        this(DEFAULT_CAPACITY);
    }

    /**
     * 有参构造
     * @param initialCapacity 默认10
     */
    public MyArrayList(int initialCapacity) {
        if(initialCapacity<0) {
            try {
                throw new Exception();
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        this.elementData=new Object[DEFAULT_CAPACITY];//
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public boolean isEmpty() {
        return size==0;
    }

    @Override
    public boolean contains(Object o) {
        return indexOf(o)>0?true:false;
    }

    @Override
    public Iterator<E> iterator() {
        return null;
    }

    @Override
    public Object[] toArray() {
        Object[] objects =  new Object[size];
        for (int i = 0; i < objects.length; i++) {
            objects[i] = elementData[i];
        }
        return objects;
    }

    @Override
    public <T> T[] toArray(T[] a) {
        for (int i = 0; i < a.length; i++) {
            a[i] = (T)elementData[i];
        }
        return a;
    }


    @Override
    public boolean remove(Object o) {
        int i = indexOf(o);
        if(i>0){
            remove(i);
            return true;
        }
        return false;
    }


    @Override
    public void clear() {
        MyArrayList<E> myArrayList = new MyArrayList<>(size);
        size=0;
    }

 

    @Override
    public boolean add(E e) {
        //1.数组是否装满
        if(size>=elementData.length){
        //扩容,采用arraycopy方法
            Object[] objects = new Object[elementData.length * 2];
            System.arraycopy(elementData,0,objects,0,size);
            elementData = objects;
        }
        elementData[size]=e;
        size = size+1;
        return true;
    }

    /**
     * 在指定位置添加元素,后面的向后移动
     * @param index
     * @param element
     */
    @Override
    public void add(int index, E element) {
        ArrayUtils.checkIndex(index,size);

        Object[] objects;
        //判断是否需要扩容
        if(size>=elementData.length){
            objects = new Object[elementData.length * 2];
        }else{
            objects = new Object[elementData.length];
        }
        size++;
        System.arraycopy(elementData,0,objects,0,index);
        objects[index] = element;

        for (int i = index; i < size; i++) {
            objects[i+1] = elementData[i];
        }
        elementData = objects;
    }

    /**
     * 删除指定位置元素,将后面的数组往前移动
     * @param index
     * @return
     */
    @Override
    public E remove(int index) {
        ArrayUtils.checkIndex(index,size);
        E e = (E)elementData[index];
        int nextLength = elementData.length;
        Object[] objects = new Object[nextLength];
        System.arraycopy(elementData,0,objects,0,elementData.length);
        for (int i = index+1; i < nextLength; i++) {
            objects[i-1] = elementData[i];
        }
        elementData = objects;
        size--;
        return e;
    }

    @Override
    public int indexOf(Object o) {
        if(o==null)return -1;
        for (int i = 0; i <elementData.length ; i++) {
            if(o.equals(elementData[i]))return i;
        }
        return -1;
    }

    @Override
    public int lastIndexOf(Object o) {
        if(o==null)return -1;
        for (int i = elementData.length-1; i <elementData.length ; i++) {
            if(o.equals(elementData[i]))return i;
        }
        return -1;
    }

  @Override
    public boolean containsAll(Collection<?> c) {
        return false;
    }

    @Override
    public boolean addAll(Collection<? extends E> c) {
        return false;
    }

    @Override
    public boolean addAll(int index, Collection<? extends E> c) {
        return false;
    }

    @Override
    public boolean removeAll(Collection<?> c) {
        return false;
    }

    @Override
    public boolean retainAll(Collection<?> c) {
        return false;
    }


    @Override
    public ListIterator<E> listIterator() {
        return null;
    }

    @Override
    public ListIterator<E> listIterator(int index) {
        return null;
    }

    @Override
    public List<E> subList(int fromIndex, int toIndex) {
        return null;
    }
  @Override
    public E get(int index) {
        ArrayUtils.checkIndex(index,size);
        return (E)elementData[index];
    }

    @Override
    public E set(int index, E element) {
        return null;
    }





}

public class ArrayUtils {

    /**
     * 数组下标越界检查
     * @param index 数组下标
     * @param size 数组大小
     * @param <X> 运行时异常
     * @return
     */
    public static <X extends RuntimeException> int checkIndex(int index,int size){
        if(index<0||index>size-1)throw new RuntimeException("数组下标越界");
        return index;
    }

}

2.代码思路

MyArrayList模仿ArrayList,毕竟List试衣镜定义好的接口,实现里面方法即可。
ArrayUtils 模仿ArrayList里面使用的工具类,判断数组下表越界。

目前实现的方法思路都有,可能还有错误或者实现思路效率低下等问题

3.测试

1.add方法和get方法

@Test
    public void test3(){
        MyArrayList<String> list = new MyArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("ads");
        list.add("asdf");
        list.add("asdf");
        list.add("gras");
        list.add("asfd");
        list.add("asdf");
        list.add("asfd");
        list.add("asfasdf");
        list.add("ads");
        System.out.println(list.size());
         Assert.assertSame("张三",list.get(0));
        Assert.assertSame("李四",list.get(1));
        Assert.assertSame("王五",list.get(2));
        Assert.assertEquals("溜溜",list.get(3));
        Assert.assertEquals("七七",list.get(4));
        Assert.assertEquals("八八",list.get(5));
        Assert.assertEquals("九九",list.get(6));
        Assert.assertEquals("试试",list.get(7));
        Assert.assertEquals("事宜",list.get(8));
        Assert.assertEquals("十二",list.get(9));
        Assert.assertEquals("十三",list.get(10));
        Assert.assertEquals("十四",list.get(11));
        list.stream().forEach(System.out::print);
   	//结果 
   	//12
   	//张三李四王五溜溜七七八八九九试试事宜十二十三十四

    }

2.remove方法

@Test
    public void test3(){
        MyArrayList<String> list = new MyArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("ads");
        list.add("asdf");
        list.add("asdf");
        list.add("gras");
        list.add("asfd");
        list.add("asdf");
        list.add("asfd");
        list.add("asfasdf");
        list.add("ads");
        System.out.println(list.size());
     	list.stream().forEach(System.out::print);
        System.out.println(list.indexOf("李四"));
        list.remove(1);
        System.out.println(list.indexOf("李四"));
        System.out.println(list.size());
        list.stream().forEach(System.out::print);
   	//结果 
   	//12
	//张三李四王五溜溜七七八八九九试试事宜十二十三十四1
	//-1
	//11
	//张三王五溜溜七七八八九九试试事宜十二十三十四

    }

2.add(int i,E e)方法

@Test
    public void test3(){
        MyArrayList<String> list = new MyArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("ads");
        list.add("asdf");
        list.add("asdf");
        list.add("gras");
        list.add("asfd");
        list.add("asdf");
        list.add("asfd");
        list.add("asfasdf");
        list.add("ads");
        System.out.println(list.size());
     	 list.stream().forEach(System.out::print);
        list.add(2,"十八");
        System.out.println(list.size());
        list.stream().forEach(System.out::print);
   	//结果 
   //12
	//张三李四王五溜溜七七八八九九试试事宜十二十三十四13
	//张三李四十八王五溜溜七七八八九九试试事宜十二十三十四

    }

目前实现的方法就这么多,下个版本实现迭代器。进行遍历等

4.结束

写这个只是为了加深对java基础的理解,希望能与大家一起分享

发布了44 篇原创文章 · 获赞 13 · 访问量 9678
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章