自己實現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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章