本身實現ArrayList

思路:java

一 載體 數組

ArrayList是一個集合容器,必然要有一個保存數據的載體。安全

public class MyArraylist {
    private final static int INIT_COUNT = 10;
    
    Object[] arrays;
    
    public MyArraylist() {
        this(INIT_COUNT);
    }

    public MyArraylist(int count) {
        arrays = new Object[count];
    } 
}

 

 

二屬性app

長度ide

獲得集合會初始化一個數組長度,集合的元素個數不能是數組長度。ui

public class MyArraylist2 {
    private int size;
    public int size(){
        return size;
    }
    
}

 

 

三方法this

增刪改查spa

增長線程

按默認索引加入元素,按索引加入元素,加入單個元素,加入批量元素。這裏只舉按單個加入元素的例子。code

首先須要判斷索引是否非法

public void checkIndexRange(int index) {
        if (index > size) {
            throw new IndexOutOfBoundsException("數組越界");
        }
    }

    public void checkIndexRangeForAdd(int index) {
        if (index > size || index < 0) {
            throw new IndexOutOfBoundsException("數組越界");
        }
}

判斷當前數組是否須要擴容。若是索引大於當前數組長度,按當前長度的50%增長。並將當前數組複製到新的數組。

public void checkIndex(int index) {
        if (index > arrays.length) {
            int oldLength = size;
            int newLength = oldLength + (index >> 1);
            arrays = Arrays.copyOf(arrays, newLength);
        }
    }

 

增長單個元素

    public void add(Object obj, int index) {
        checkIndexRangeForAdd(index);//判斷索引是否非法
        checkIndex(size + 1);//判斷數組是否須要擴容
        System.arraycopy(arrays, index, arrays, index + 1, size - index);
        arrays[index] = obj;
        size++;
    }

    public boolean add(Object obj) {
        checkIndex(size + 1);//判斷數組是否須要擴容
        arrays[size++] = obj;
        return true;
    }

 

獲取元素

public T get(int index) {
        checkIndexRangeForAdd(index);
        return (T) arrays[index];
    }

 

更新元素

    public T set(Object obj, int index) {
        checkIndexRange(index);
        T t = (T) arrays[index];
        arrays[index] = obj;
        return t;
    }

 

刪除元素

public T remove(int index) {
        checkIndexRange(index);

        T t = (T) arrays[index];
        int moveLength = size - index - 1;
        if (moveLength > 0) {
            System.arraycopy(arrays, index + 1, arrays, index, moveLength);
        }
        arrays[--size] = null;
        return t;
    }

 

四迭代

使用加強型for循環迭代輸出,以及Java 8引進的lambda表達式實現foreach。

 

首先生成一個迭代器。

private class MyArrayListIterator implements Iterator<T> {

        private int count;
 
        public boolean hasNext() {
            return count != size;
        }

        public T next() {
            checkModcount();
            return (T) arrays[count++];
        } 
         
    }

而後繼承Iterable接口。

public class MyArraylist2<T> implements Iterable<T>{
 

    @Override
    public Iterator<T> iterator() {
        return new MyArrayListIterator();
    }

     
    
}

 

 

 

五線程安全問題

ArrayList沒有實現線程安全,可是在迭代的時候,不容許修改。

ArrayList使用一個成員變量modCount在迭代開始的時候記錄ArrayList正在作修改(增長,修改,刪除)的數量,而後在每迭代一行的時候,去比較modCount是否發生變化。若是發生變化,證實此刻有其它的線程或者就是本線程就對它進行修改,而後拋出異常。

定義modcount變量。

private transient int modcount;

在增長,修改,刪除的時候,均需將此值加1。

 

public boolean add(Object obj) {
        checkIndex(size + 1);
        modcount++;//加1
        arrays[size++] = obj;
        return true;
    }

    public void checkIndex(int index) {
        if (index > arrays.length) {
            modcount++;//加1
            int oldLength = size;
            int newLength = oldLength + (index >> 1);
            arrays = Arrays.copyOf(arrays, newLength);
        }
    }

 

public T set(Object obj, int index) {
        checkIndexRange(index);
        modcount++;//加1
        T t = (T) arrays[index];
        arrays[index] = obj;
        return t;
    }

 

public T remove(int index) {
        checkIndexRange(index);
        modcount++;//加1

        @SuppressWarnings("unchecked")
        T t = (T) arrays[index];
        int moveLength = size - index - 1;
        if (moveLength > 0) {
            System.arraycopy(arrays, index + 1, arrays, index, moveLength);
        }
        arrays[--size] = null;
        return t;
    }

 

在迭代的時候,將此值賦給另外一個變量exceptCount。而後再每迭代一行的時候,將exceptCount與modcount比較。

private class MyArrayListIterator implements Iterator<T> {

     

        private int exceptCount = modcount; 

        public void checkModcount() {
            if (exceptCount != modcount) {
                throw new ConcurrentModificationException();
            }
        }

    }

 

最後實現的所有代碼

package com.skycomm.sdf;

import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.Iterator;

public class MyArraylist<T> implements Iterable<T> {

    private final static int INIT_COUNT = 10;

    private int size = 0;

    private transient int modcount;

    Object[] arrays;

    public MyArraylist() {
        this(INIT_COUNT);
    }

    public MyArraylist(int count) {
        arrays = new Object[count];
    }

    public void add(Object obj, int index) {
        checkIndexRangeForAdd(index);
        checkIndex(size + 1);
        System.arraycopy(arrays, index, arrays, index + 1, size - index);
        arrays[index] = obj;
        size++;
    }

    public boolean add(Object obj) {
        checkIndex(size + 1);
        modcount++;//加1
        arrays[size++] = obj;
        return true;
    }

    public void checkIndex(int index) {
        if (index > arrays.length) {
            modcount++;//加1
            int oldLength = size;
            int newLength = oldLength + (index >> 1);
            arrays = Arrays.copyOf(arrays, newLength);
        }
    }

    public T get(int index) {
        checkIndexRangeForAdd(index);
        return (T) arrays[index];
    }

    public T remove(int index) {
        checkIndexRange(index);
        modcount++;//加1

        @SuppressWarnings("unchecked")
        T t = (T) arrays[index];
        int moveLength = size - index - 1;
        if (moveLength > 0) {
            System.arraycopy(arrays, index + 1, arrays, index, moveLength);
        }
        arrays[--size] = null;
        return t;
    }

    public T set(Object obj, int index) {
        checkIndexRange(index);
        modcount++;//加1
        T t = (T) arrays[index];
        arrays[index] = obj;
        return t;
    }

    public void checkIndexRange(int index) {
        if (index > size) {
            throw new IndexOutOfBoundsException("數組越界");
        }
    }

    public void checkIndexRangeForAdd(int index) {
        if (index > size || index < 0) {
            throw new IndexOutOfBoundsException("數組越界");
        }
    }

    public int size() {
        return size;
    }

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

    public String toString() {
        Iterator<T> it = iterator();
        if (!it.hasNext())
            return "[]";

        StringBuilder sb = new StringBuilder();
        sb.append('[');
        for (;;) {
            T e = it.next();
            sb.append(e == this ? "(this Collection)" : e);
            if (!it.hasNext())
                return sb.append(']').toString();
            sb.append(',').append(' ');
        }
    }

    public Iterator<T> iterator() {
        return new MyArrayListIterator();
    }

    private class MyArrayListIterator implements Iterator<T> {

        private int count;

        private int exceptCount = modcount;

        public boolean hasNext() {
            return count != size;
        }

        public T next() {
            checkModcount();
            return (T) arrays[count++];
        }

        public void checkModcount() {
            if (exceptCount != modcount) {
                throw new ConcurrentModificationException();
            }
        }

    }

}
View Code
相關文章
相關標籤/搜索