package com.java; import java.util.Arrays; public class MyArrayList { private final static int DEFAULT_SIZE = 10; private Object[] arr; // 首先是構造方法 // 查詢api發現arraylist有三個構造方法 // 第一個構造初始容量爲10的空列表 int size; public MyArrayList() { this(DEFAULT_SIZE); } // 第二個指定元素類型的 ,使用泛型的暫時不做了 // 第三個構造具有指定容量的空列表 public MyArrayList(int arrlenght) { if (arrlenght < 0) { throw new NoRangeException("輸入的範圍不對"); } else { arr = new Object[arrlenght]; } } // 第一個方法 將指定元素追加到此列表末尾 public boolean add(Object o) { // 首先判斷要不要判斷會不會超出範圍 judgeRange(size + 1); arr[size++] = o; return true; } public void judgeRange(int size) { if (size + 1 > arr.length) { // 當size表示這次要添加的位置,判斷size+1是不是大於數組的長度了 大於就要擴充數組 expand(size); } } private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; public void expand(int size) { int oldsize = arr.length; int newsize = oldsize + (oldsize >> 1);// 位運算 向右移動一位,相當於原來的1/2 // 將數組擴大到原來的1.5倍 if (newsize < size) { newsize = size; // 如果1.5倍長度不夠就申請需要的長度,如果增加一個的話是用不到這個方法的, // 主要用於addAll的時候一次增加元素導致一次1.5倍不夠. } if (newsize > MAX_ARRAY_SIZE) newsize = (size > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; // 當list長到大於上面定義的最大的長度,就把長度擴展到int的最大值,否則使用上面定義的那個 arr = Arrays.copyOf(arr, newsize); } // 第二個方法 在此列表中的指定位置插入指定元素 public void add(int index, Object o) { // 首先判斷要插入的位置在不在有效的範圍 judgeAddRange(index); // 然後判斷需不需要擴容 judgeRange(size + 1); // 將index及以後的元素向後移動一位 System.arraycopy(arr, index, arr, index + 1, size - index); arr[index] = o; // index下標的內容改爲o size++; } // 判斷範圍 public void judgeAddRange(int index) { if (index < 0 && index > size) { throw new IndexOutOfBoundsException("index越界"); } } // 從列表中刪除所有元素 public void clear() { for (int i = 0; i < size; i++) { arr[i] = null; } size = 0; } // 返回此列表實例的淺拷貝 也不知道對不對,不會死很懂這個clone,也不會驗證 public Object clone() { MyArrayList v = null; try { v = (MyArrayList) super.clone(); v.arr = Arrays.copyOf(arr, size); } catch (CloneNotSupportedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return v; } // 如果此列表包含指定的元素,則返回true public boolean contains(Object o) { return indexOf(o) > -1; } // 返回此列表中指定元素的第一次出現的索引,如果此類表不包含元素,則返回-1 public int indexOf(Object o) { if (o == null) { for (int i = 0; i < size; i++) if (arr[i] == null) return i; } else { for (int i = 0; i < size; i++) if (o.equals(arr[i])) return i; } return -1; } // 返回此類表中指定位置的元素 public Object get(int index) { // 判斷範圍 rangeForRemove(index); return arr[index]; } // 如果此列表不包含元素,則返回true public boolean isEmpty() { return size() == 0; } // 返回列表中的元素 public int size() { return size; } // 刪除該列表中指定位置的元素 public Object remove(int index) { // 先判斷範圍 rangeForRemove(index); Object oldo = arr[index]; int moveSize = size - index - 1; if (moveSize > 0) // 判斷刪除的是不是最後一個元素,覆蓋 System.arraycopy(arr, index + 1, arr, index, size - index - 1); arr[--size] = null; // 後面的賦值爲null return oldo; } // 從列表中刪除指定元素的第一個出現(如果存在) public boolean remove(Object o) { // 首先看有沒有這個元素 if (contains(o)) { remove(indexOf(o)); return true; } return false; } // 從這個列表中刪除所有索引在intfromIndex(含)和toIndex之間的元素 protected void removeRange(int intFromIndex, int toIndex) { System.arraycopy(arr, toIndex, arr, intFromIndex, size - toIndex); int newsize = size - toIndex + intFromIndex; for (int i = newsize; i < size; i++) { arr[i] = null; } size = newsize; } private void rangeForRemove(int index) { if (index >= size || index < 0) throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); } @Override public String toString() { return "MyArrayList [arr=" + Arrays.toString(arr) + ", size=" + size + "]"; } }
收穫
arraylist默認的大小是10.
arraylist擴充容量會是原來的1.5倍,如果1.5被不夠那麼就擴招到需要的容量,當然最大的範圍是Integer的最大值.但是爲什麼會默認保留8位呢,或許保存着一些東西,或許是爲了跨平臺???防止在有些機器上出問題,爲什麼要默認-8,又能個擴展到最大啊
判斷元素的時候先判斷是不是爲null 也就是說這個集合支持存null的
底層是數組的話,是不是意味着他在增加和刪除方面比較慢,在查詢方面比較快.但是好像和其他的對象也有點關係.
用System.arraycopy來是實現元素的覆蓋.增刪.
用Arrays.copyOf來實現擴容.