自己实现基于数组的ArrayList的基本api
写一个自己的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; //不允许在当前游标位置进行修改,如果修改就会发生逻辑错误 } } }