本着更加深刻的理解ArrayList的目的,所以自己實現一個簡單的ArrayList,只是實現了List接口,實現了大部分的方法,其實還有一些地方不完善,比如對於參數的異常判斷,返回值的判斷,還有常數的直接使用。其實只要明白其中的原理即可。
MyArrayList類:
package testpackge.util; import java.util.*; /** * 自己實現ArrayList有,實現List接口,實現大部分方法 * * @Authoc: Alic(1071631279 @ qq.com) * @creattime: 2018/5/420:11 */ public class MyArrayList<E> implements List<E>{ /** * MArrayList內部實際是一個object數組,初始化默認是一個空的數組 */ private Object[] elementData = {}; /** * 集合中數據的個數 */ private int size; /** * 默認空參構造 */ public MyArrayList(){ } /** *有參構造 * @param capacity 初始化容量 */ public MyArrayList(int capacity){ this.elementData = new Object[capacity]; } /** * 集合作爲構造參數 * @param c 初始化加入的集合 */ public MyArrayList(Collection<? extends E> c){ this.elementData = c.toArray(); this.size = c.size(); } /** * 添加元素,默認添加到末尾 * @param e 添加的元素 * @return 返回false */ public boolean add(E e) { //擴容方法 grow(size+1); //把元素添加到元素的末尾 elementData[size++] = e; return true; } /** * 在指定位置添加元素 * @param index 指定索引位置 * @param element 添加的元素 */ public void add(int index, E element) { //越界檢查 if(index>size||index<0){ throw new RuntimeException("ArrayIndexOutOfBoundsException"); } //擴容 grow(size+1); //把elementData的index及後面的size-index個元素複製到elementData的index+1開始的位置上 System.arraycopy(elementData,index,elementData,index+1,size-index); //index賦值element elementData[index] = element; //size增加 size++; } /** * 添加一個集合 * @param c 添加的集合 * @return 返回false */ public boolean addAll(Collection<? extends E> c) { //轉換爲數組 Object[] objects = c.toArray(); //數組長度 int num = objects.length; //擴容操作 grow(size+num); //把objects的0開始的num個元素複製到elementData的size開始的位置上 System.arraycopy(objects, 0, elementData, size, num); //更改size的值 size += num; return true; } /** * 指定位置添加一個集合 * @param index 指定位置索引 * @param c 添加的集合 * @return 返回true */ public boolean addAll(int index, Collection<? extends E> c) { //越界檢查 if(index>size||index<0){ throw new RuntimeException("ArrayIndexOutOfBoundsException"); } //轉換爲數組 Object[] objects = c.toArray(); //數組的長度 int num = objects.length; //擴容 grow(size+num); //把elementData的index開始的size-index個元素複製到elementData的index+num開始的位置上 System.arraycopy(elementData,index, elementData, index+num, size-index); //把objects的0開始的num個元素複製到elementData的index開始的位置上 System.arraycopy(objects,0, elementData, index, num); //更新size的值 size += num; return true; } /** * 擴容方法 * @param capacity 需要的最小容量值 */ private void grow(int capacity){ //集合目前的容量 int oldcapacity = elementData.length; //如果集合初始化爲添加任何元素,空的數組 if(oldcapacity==0){ //默認容量10 elementData = new Object[10]; }else { //把容量擴大至原來的1.5倍 while (capacity < oldcapacity) { //把elementData的數據複製到capacity大小的新數組中並且返回, elementData = Arrays.copyOf(elementData, capacity = oldcapacity + oldcapacity >> 1); } } } /** * 移除o元素 * @param o 刪除元素 * @return 找到刪除返回true,否則返回false */ public boolean remove(Object o) { //獲取索引位置 int indexOf = indexOf(o); if(indexOf>=0){ //刪除索引indexOf的元素 remove(indexOf); return true; } return false; } /** * 刪除index的元素 * @param index 索引位置 * @return 返回對應元素 */ public E remove(int index) { //越界檢查 if(index>size||index<0){ throw new RuntimeException("ArrayIndexOutOfBoundsException"); } E e = (E)elementData[index]; //把elementData的index+1開始的size-index-1個元素複製到elementData的index開始的位置上 System.arraycopy(elementData,index+1,elementData,index,size-index-1); //把最後一個元素置爲null,便於GC,size更新 elementData[size--] = null; return e; } /** * 移除c的全部集合 * @param c 集合對象 * @return 返回true */ public boolean removeAll(Collection<?> c) { //迭代器迭代刪除 Iterator<?> iterator = c.iterator(); while(iterator.hasNext()){ Object next = iterator.next(); remove(next); } return true; } /** * 獲取o對應的索引 * @param o 查找的對象 * @return 返回對應索引位置,找到就返回 */ public int indexOf(Object o) { //如果是null值,循環遍歷判斷有無null值 if(o==null){ for(int i = 0;i<size;i++){ if(elementData[i]==null){ return i; } } }else{ //循環遍歷判斷,使用equals判斷是否相等 for(int i = 0;i<size;i++){ if(o.equals(elementData[i])){ return i; } } } return -1; } /** * 獲取集合中最後一個o值 * @param o 獲取o相等的值 * @return 返回對應的索引位置 */ public int lastIndexOf(Object o) { //循環從後向前白遍歷 if(o==null){ for(int i = size-1;i>=0;i--){ if(elementData[i]==null){ return i; } } }else{ for(int i = size-1;i>=0;i--){ if(o.equals(elementData[i])){ return i; } } } return -1; } /** * 獲取size的值 * @return 返回size值 */ public int size() { return size; } /** * 判斷是否爲空,即判斷size是否爲0 * @return 爲空返回true,否則返回false */ public boolean isEmpty() { return size==0; } /** * 判斷是否包含o值,如果indexOf返回-1就沒有對應的值 * @param o 判斷包含的值 * @return 包含就返回true,否則返回false */ public boolean contains(Object o) { return indexOf(o)>=0; } /** * 是否包含c中所有的值 * @param c 判斷的集合對象 * @return 全部包含返回true,否則返回false */ public boolean containsAll(Collection<?> c) { //迭代判斷,有一個不是就返回false Iterator<?> iterator = c.iterator(); while(iterator.hasNext()){ Object next = iterator.next(); if(indexOf(next)<0){ return false; } } return true; } /** * 清除集合元素 */ public void clear() { //循環遍歷置爲null.便於GC for(int i = size-1;i>=0;i--){ elementData[i]=null; } //更改size爲0 size = 0; } /** * 獲取index所有上的值 * @param index * @return 返回對應的元素 */ public E get(int index) { //越界檢查 if(index>size||index<0){ throw new RuntimeException("ArrayIndexOutOfBoundsException"); } return (E)elementData[index]; } /** * 更新index上的值爲element * @param index * @param element * @return 返回index舊的值 */ public E set(int index, E element) { //越界檢查 if(index>size||index<0){ throw new RuntimeException("ArrayIndexOutOfBoundsException"); } //index的原始值 E e = (E)elementData[index]; //更改index的引用爲element elementData[index] = element; return e; } /** * 轉換爲數組 * @return 返回數組 */ public Object[] toArray() { //創建一個長度爲size的數組,循環遍歷賦值 Object[] objects = new Object[size]; for(int i = 0;i<size;i++){ objects[i]=elementData[i]; } return objects; } /** * 截取formIndex到toIndex的值的集合,包含左右邊界 * @param fromIndex 起始值 * @param toIndex 結束值 * @return 返回截取的集合 */ public List<E> subList(int fromIndex, int toIndex) { //越界檢查,已經確保fromIndex小於等於toIndex if(fromIndex>size||fromIndex<0||toIndex>size||toIndex<0||fromIndex>toIndex){ throw new RuntimeException("ArrayIndexOutOfBoundsException"); } //創建新的對象 MyArrayList<E> myArrayList = new MyArrayList(); //創建toIndex-fromIndex+1長度的數組 Object[] objects = new Object[toIndex-fromIndex+1]; //遍歷賦值 for(int i = fromIndex;i<=toIndex;i++){ objects[i]=elementData[i]; } //設置size值 myArrayList.size = toIndex-fromIndex+1; //設置集合的元素數組 myArrayList.elementData = objects; return myArrayList; } /** * 重寫toString方法 * @return 返回集合數據的字符串 */ @Override public String toString() { //創建stringBuder對象 StringBuilder stringBuilder = new StringBuilder(); //遍歷拼接字符串,每一個對象加一個"," stringBuilder.append("["); for(int i = 0;i<size;i++){ stringBuilder.append(((E)elementData[i]).toString()); stringBuilder.append(","); } //清除最後一個","字符 int lastIndexOf = stringBuilder.lastIndexOf(","); if(lastIndexOf>0){ stringBuilder.deleteCharAt(lastIndexOf); } stringBuilder.append("]"); return stringBuilder.toString(); } /** * 迭代器對象 */ public class Itr implements Iterator<E>{ /** * 迭代到的索引位置 */ private int cursor; /** * 是否還有下一個元素,即判斷迭代位置是否已到size * @return 還有返回true,沒有返回false */ @Override public boolean hasNext() { return cursor!=size; } /** * 返回下一個元素,直接返回elementData的對應數據 * @return 返回對應元素 */ @Override public E next() { return (E)elementData[cursor++]; } } /** * 返回迭代器對象,創建一個內部類 * @return 內部類迭代器對象 */ public Iterator<E> iterator() { return new Itr(); } //下面的方法其實都是一樣的,只要明白了其中的原理即可,以下四個方法不實現了 public ListIterator<E> listIterator() { return null; } public ListIterator<E> listIterator(int index) { return null; } public boolean retainAll(Collection<?> c) { return false; } public <T> T[] toArray(T[] a) { return null; } }
Main測試代碼:
MyArrayList<ClassA> myArrayList = new MyArrayList(); ClassA a1 = new ClassA(12,"a1"); ClassA a2 = new ClassA(13,"a2"); ClassA a3 = new ClassA(14,"a3"); ClassA a4 = new ClassA(15,"a4"); System.out.println("------初始化後------"); System.out.println("size:"+myArrayList.size()); System.out.println("------開始添加元素------"); myArrayList.add(a1); System.out.println(myArrayList); System.out.println("contrins方法,是否包含a1:"+myArrayList.contains(a1)); System.out.println("size:" + myArrayList.size()); System.out.println("在1位置添加一個元素a2"); myArrayList.add(1,a2); System.out.println(myArrayList); System.out.println("size:" + myArrayList.size()); System.out.println("在2位置添加一個元素a3"); myArrayList.add(2,a3); System.out.println(myArrayList); System.out.println("size:" + myArrayList.size()); System.out.println("獲取2位置上的元素:"+myArrayList.get(2)); System.out.println("獲取a1元素的索引位置:" + myArrayList.indexOf(a1)); System.out.println("判斷集合是否爲空:" + myArrayList.isEmpty()); System.out.println("移除索引爲1的元素:"); myArrayList.remove(1); System.out.println(myArrayList); System.out.println("size:" + myArrayList.size()); System.out.println("移除a3:"); myArrayList.remove(a3); System.out.println(myArrayList); System.out.println("size:" + myArrayList.size()); System.out.println("添加a2元素"); myArrayList.add(a2); System.out.println(myArrayList); System.out.println("size:" + myArrayList.size()); System.out.println("更新索引1位置的元素爲a4"); myArrayList.set(1,a4); System.out.println(myArrayList); System.out.println("添加a3元素"); myArrayList.add(a3); System.out.println(myArrayList); System.out.println("size:" + myArrayList.size()); System.out.println("截取索引爲0-2的元素,得到subList:"); List<ClassA> subList = myArrayList.subList(0, 2); System.out.println(subList); System.out.println("clear方法清空subList:"); subList.clear(); System.out.println(subList); System.out.println("toArray方法得到數組:"); Object[] objects = myArrayList.toArray(); for (int i = 0,len = myArrayList.size();i<len;i++){ System.out.println(myArrayList.get(i)); } System.out.println("迭代器測試:"); Iterator<ClassA> iterator = myArrayList.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } System.out.println("有參構造得到arrayList"); MyArrayList arrayList = new MyArrayList(myArrayList);
System.out.println(arrayList);
輸出結果:
------初始化後------
size:0
------開始添加元素------
[ClassA{age=12, name='a1'}]
contrins方法,是否包含a1:true
size:1
在1位置添加一個元素a2
[ClassA{age=12, name='a1'},ClassA{age=13, name='a2'}]
size:2
在2位置添加一個元素a3
[ClassA{age=12, name='a1'},ClassA{age=13, name='a2'},ClassA{age=14, name='a3'}]
size:3
獲取2位置上的元素:ClassA{age=14, name='a3'}
獲取a1元素的索引位置:0
判斷集合是否爲空:false
移除索引爲1的元素:
[ClassA{age=12, name='a1'},ClassA{age=14, name='a3'}]
size:2
移除a3:
[ClassA{age=12, name='a1'}]
size:1
添加a2元素
[ClassA{age=12, name='a1'},ClassA{age=13, name='a2'}]
size:2
更新索引1位置的元素爲a4
[ClassA{age=12, name='a1'},ClassA{age=15, name='a4'}]
添加a3元素
[ClassA{age=12, name='a1'},ClassA{age=15, name='a4'},ClassA{age=14, name='a3'}]
size:3
截取索引爲0-2的元素,得到subList:
[ClassA{age=12, name='a1'},ClassA{age=15, name='a4'},ClassA{age=14, name='a3'}]
clear方法清空subList:
[]
toArray方法得到數組:
ClassA{age=12, name='a1'}
ClassA{age=15, name='a4'}
ClassA{age=14, name='a3'}
迭代器測試:
ClassA{age=12, name='a1'}
ClassA{age=15, name='a4'}
ClassA{age=14, name='a3'}
有參構造得到arrayList
[ClassA{age=12, name='a1'},ClassA{age=15, name='a4'},ClassA{age=14, name='a3'}]