思路: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(); } } } }