自己實現基於陣列的ArrayList的基本api
阿新 • • 發佈:2020-08-15
寫一個自己的ArrayList
* 集合類 容器
*
* 1 裡面提供了哪些操作? 參考List介面
*
* 2 裡面有哪些資料? 成員變數 分析
*
* 3 構造方法;
介面List
import java.util.Iterator; import java.util.ListIterator; public interface List<E> { boolean add(E e); void add(int index,E e); void remove(E e); E remove(int index); boolean contains(E e); void clear(); E get(int index); int indexof(E e); int lastIndexof(E e); void set(int index,E e); int size(); boolean isEmpty(); ListIterator<E> iterator(); ListIterator<E> iterator(int index); }
Test
package javahomework.day29; import java.util.ListIterator; public class Test { public static void main(String[] args) { MyList<String> ms = new MyList<>(); boolean empty = ms.isEmpty(); //System.out.println(empty); ms.add("a"); ms.add("b"); ms.add("d"); ms.add("e"); ms.add("a"); System.out.println(ms.size); //ms.remove(1); System.out.println(ms); ListIterator listIterator = ms.iterator(); while(listIterator.hasNext()){ Object next = listIterator.next(); if("a".equals(next)){ ms.remove(next); //listIterator.add("java"); } } while(listIterator.hasPrevious()){ Object previous = listIterator.previous(); if("a".equals(previous)){ //listIterator.add("java"); } } System.out.println(ms); } }
MyList
package javahomework.day29; import java.util.Arrays; import java.util.ConcurrentModificationException; import java.util.ListIterator; import java.util.NoSuchElementException; /* * 寫一個自己的ArrayList */ public class MyList<E> implements List<E> { public Object[] element;//儲存資料的陣列 int size;//資料元素的個數 int modecount;//集合修改的次數 private static final int Defaultcapcity = 10; //預設分配的容量 private static final int Max_arry = Integer.MAX_VALUE-8;//最大陣列容量 //無參構造,分配預設的容量Defaultcapcity public MyList(){ element = new Object[Defaultcapcity]; } //有參構造,分配指定容量 public MyList(int capcity) { //判斷引數是否合法 if(capcity<0||capcity>Max_arry){ throw new IllegalArgumentException("非法引數"); } element = new Object[capcity]; } /** * toString方法 把集合元素輸出 * @return 返回集合元素的字串 */ @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("["); if(size>0){ for(int i =0; i < size-1; i++){ sb.append(element[i]+" "); } sb.append(element[size-1]); } sb.append("]"); return sb.toString(); } /** * 在集合末尾增加一個元素 * @param o 任意指定型別 * @return 返回true新增成功 */ @Override public boolean add(Object o) { add(size,o); return true; } /** * 在index位置新增元素 * @param index 集合的索引位置 * @param o 任意型別資料 */ @Override public void add(int index, Object o) { checkIndex(index); //檢查索引是否合法 int mincapcity = size+1; //要新增元素,那麼最小容量至少為size+1 if(mincapcity>element.length){ //判斷最小需要的容量與分配的容量的大小,決定是否需要擴容 int newcapcity = element.length+(element.length<<1); //新的容量一般為原容量的1.5倍 if(newcapcity<0||newcapcity>Max_arry){ //如果新的容量不符合容量的要求 newcapcity = Max_arry; //直接把新的容量設為容量最大值 } if(mincapcity>newcapcity){ //計算好新的容量後,比較最小需要的容量和新的容量,二者的較大值才為需要的新的的容量 newcapcity= mincapcity; } Object[] objects = new Object[newcapcity];//用需要的容量建立新的陣列 for(int i=0;i<newcapcity;i++){ //新的陣列存入element陣列的資料 objects[i] = element[i]; } element = objects; //element陣列指向新陣列引用 } for(int i = size; i>index; i--){ //開始新增資料,首先把新增位置後的資料都向後移動 element[i] = element[i-1]; } element[index] = o; //在要新增的位置新增資料 modecount++; //修改集合次數+1 size++; //集合元素個數+1 } /** * 檢查索引是否合法 * @param index 索引 */ private void checkIndex(int index) { if(index<0||index>size){ throw new IllegalArgumentException("非法引數"); } } /** * 移除指定元素(有重複的移動位置最前的) * @param o */ @Override public void remove(Object o) { int index = indexof(o); if(index!=-1){ //如果索引可以找到 remove(index); } } /** * 移除指定位置的元素 * @param index 索引 * @return 返回移除的元素 */ @Override public E remove(int index) { checkIndex(index); //檢查索引是否合法 E e = (E) element[index]; //臨時儲存所移除元素 for (int i = index; i <size ; i++) { //移除元素,需要把index之後的 元素向前移動 element[i] = element[i+1]; } element[size] = null; //移除後空出位置需要置為空 size--; //元素個數-1 modecount++; //修改集合次數+1 return e; } /** * 判斷集合中是否包含此元素 * @param e 任意型別資料 * @return 返回true表示找到,否則返回false */ @Override public boolean contains(E e) { int i = indexof(e); return i!=-1; } /** * 清空集合元素 */ @Override public void clear(){ for (int i = 0; i < size; i++) { element[i] =null; //所有元素置為空 } size = 0; //元素個數置為0 modecount++; //修改集合次數+1 } /** * 得到集合指定位置的元素 * @param index 索引 * @return 返回指定位置的元素 */ @Override public E get(int index) { checkIndex(index); //判斷索引是否合法 return (E) element[index]; } /** * 找到指定元素的位置 * @param o 任意型別 * @return 找到返回元素位置,否則返回-1 */ @Override public int indexof(Object o) { for (int i = 0; i < size; i++) { if(element[i].equals(o)){ return i; } } return -1; } /** * 找到指定元素最後一個的位置 * @param o 任意型別 * @return 找到返回元素位置,否則返回-1 */ @Override public int lastIndexof(Object o) { for (int i = size-1; i >=0; i--) { //從後向前找方便 if(element[i].equals(o)){ return i; } } return -1; } /** * 修改集合指定位置的元素 * @param index 索引 * @param o 任意型別 */ @Override public void set(int index, Object o) { checkIndex(index); //檢查索引合法性 element[index] = o; } /** * 返回集合元素個數 * @return size */ @Override public int size() { return size; } /** * 判斷集合是否為空 * @return 為空返回true,否則返回false */ @Override public boolean isEmpty() { return size==0; } /** * 迭代器無參構造 * @return ListIterator<E> */ @Override public ListIterator<E> iterator() { return new MyIterator(); } /** * 迭代器有參構造 * @param index 索引 * @return ListIterator<E> */ @Override public ListIterator<E> iterator(int index) { return new MyIterator(index); } //成員內部類實現迭代器 public class MyIterator<E> implements ListIterator<E> { int cursor; //遊標 int lastRet=-1; //記錄上一次next或previous返回元素的索引位置 int expectedmodecount = modecount; //記錄集合修改次數,用於檢查是否出現併發修改 public MyIterator(int cursor) { //迭代器有參構造 if(cursor<0||cursor>size){ //遊標合法性,對應size throw new IllegalArgumentException("-1"); } this.cursor = cursor; } public MyIterator() {} //無參構造 /** * 判斷是否有下一個元素 * @return 有返回true,否則返回false */ @Override public boolean hasNext() { return cursor<size; //遊標對應size } /** * * @return 返回遊標的下一個元素 */ @Override public E next() { checkBinfa(); //併發檢查 if(hasNext()){ //有下一個元素 E e = (E) element[cursor]; //儲存下一個元素 lastRet=cursor; //記錄上一次next或previous返回元素的索引位置 cursor++; //遊標後移 return e; }else { throw new NoSuchElementException(); } } /** * 檢查是否發生併發修改 */ private void checkBinfa() { if(expectedmodecount!=modecount){ throw new ConcurrentModificationException(); } } /** * 判斷是否有前一個元素 * @return 有的話返回true,沒有返回false */ @Override public boolean hasPrevious() { return cursor>0; } /** * * @return 返回遊標的上一個元素 */ @Override public E previous() { checkBinfa(); //併發修改檢查 if(hasPrevious()){ //有上一個元素 E e = (E) element[cursor-1]; //儲存上一個元素 cursor--; //遊標前移 lastRet = cursor; //記錄上一次next或previous返回元素的索引位置 return e; }else{ throw new NoSuchElementException(); } } /** * * @return 返回對 next 的後續呼叫所返回元素的索引。 */ @Override public int nextIndex() { return cursor; } /** * * @return 返回對 previous 的後續呼叫所返回元素的索引。 */ @Override public int previousIndex() { return cursor--; } /** * 移除next 或者 previous 返回的最後一個位置的元素 */ @Override public void remove() { if(lastRet==-1){ //如果已經修改過,就不再允許在當前遊標位置進行修改 throw new IllegalStateException(); } checkBinfa(); //併發修改檢查 MyList.this.remove(cursor); //刪掉 expectedmodecount = modecount;//迭代器的自身的修改不會引發併發修改異常 cursor = lastRet; //這裡next和previous統一處理即可 lastRet=-1; //不允許在當前遊標位置進行修改,如果修改就會發生邏輯錯誤 } /** * 修改curcor位置的元素的值 * @param e */ @Override public void set(E e) { if(lastRet == -1){ // 如果已經修改過,就不再允許在當前遊標位置進行修改 throw new IllegalStateException(); } checkBinfa(); MyList.this.set(cursor,e); } /** * 在當前curcor位置新增一個元素 * @param e */ @Override public void add(E e) { if(lastRet==-1){ // 如果已經修改過,就不再允許在當前遊標位置進行修改 throw new IllegalStateException(); } checkBinfa(); //併發修改檢查 MyList.this.add(cursor,e); expectedmodecount = modecount;//迭代器的自身的修改不會引發併發修改異常 cursor++; //遊標後移 lastRet = -1; //不允許在當前遊標位置進行修改,如果修改就會發生邏輯錯誤 } } }