手写ArrayList
Posted 谢哥在彼方
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手写ArrayList相关的知识,希望对你有一定的参考价值。
ArrayList是Java中最为简单也是最为常用的容器之一,那么它的内部构造是什么呢?其实ArrayList的底层实现就是数组,它的各种方法就是对数组进行的一系列操作,例如对数组元素的修改,删除,位移,对数组长度的获取等。我们可以手写一个ArrayList容器,以助我们更好的理解这个容器:
1 package ArraryList; 2 3 import java.util.Arrays; 4 import java.util.Iterator; 5 6 /** 7 * 深入迭代器的原理-->一个容器可以创建多个迭代器对象 8 * 1.使用了内部类,实现迭代器 9 * 2.使用Iterable实现foreach迭代 10 * @author XieHuazhen 11 * 12 */ 13 public class MyArrayList<E> implements Iterable<E>{ //迭代器接口 14 15 //数组存储值 16 private Object[] elementData; 17 //大小 18 private int size; 19 20 public MyArrayList(int initialCapacity) { 21 if(initialCapacity>=0) { 22 elementData = new Object[initialCapacity]; 23 }else { 24 try { 25 throw new MyException(); 26 }catch(MyException e) { 27 e.printInit(); 28 } 29 } 30 } 31 32 public MyArrayList() { 33 this(0); 34 } 35 36 @SuppressWarnings("unchecked") 37 private E elementData(int index) { 38 return (E)elementData[index]; 39 } 40 41 private void ensureCapacity() { 42 if(size>=elementData.length) { 43 elementData = Arrays.copyOf(elementData,size*2+1); 44 } 45 } 46 47 private void rangeCheck(int index) { 48 if(index<0||index>=size) { 49 try { 50 throw new MyException(); 51 } catch (MyException e) { 52 e.printIndex(); 53 } 54 } 55 } 56 57 public int size() { 58 return size; 59 } 60 61 public boolean isEmpty() { 62 return size==0; 63 } 64 65 public boolean contains(Object o) { 66 return indexOf(o)>=0; 67 } 68 69 public int indexOf(Object o) { 70 for(int i=0;i<size;++i) { 71 if(elementData[i].equals(o)) 72 return i; 73 } 74 return -1; 75 } 76 77 public E get(int index) { 78 rangeCheck(index); 79 return elementData(index); 80 } 81 82 public E set(int index,E element) { 83 rangeCheck(index); 84 E oldValue = elementData(index); 85 elementData[index] = element; 86 return oldValue; 87 } 88 89 public void add(E element) { 90 ensureCapacity(); 91 elementData[size++] = element; 92 } 93 94 public void add(int index,E element) { 95 rangeCheck(index); 96 ensureCapacity(); 97 System.arraycopy(elementData,index,elementData,index+1,size-index); 98 elementData[index] = element; 99 ++size; 100 } 101 102 public E remove(int index) { 103 rangeCheck(index); 104 E oldValue = elementData(index); 105 System.arraycopy(elementData,index+1,elementData,index,size-index-1); 106 elementData[--size] = null; 107 return oldValue; 108 } 109 110 public boolean remove(E element) { 111 for(int i=0;i<size;++i) { 112 if(elementData[i].equals(element)) { 113 remove(i); 114 return true; 115 } 116 } 117 return false; 118 } 119 120 //实现Iterable<E>接口的方法 121 @Override 122 public Iterator<E> iterator() { 123 return new MyIter(); 124 } 125 126 //内部类 127 private class MyIter implements Iterator<E>{ 128 //计数器-->指针 游标 129 private int cursor; 130 private int lastRet = -1; 131 132 //判断是否存在下一个 133 @Override 134 public boolean hasNext() { 135 return cursor!=size; 136 } 137 138 //返回游标当前位置,并把游标移到下一位置 139 @SuppressWarnings("unchecked") 140 @Override 141 public E next() { 142 if(!hasNext()) { 143 try { 144 throw new MyException(); 145 } catch (MyException e) { 146 e.printnext(); 147 } 148 } 149 lastRet = cursor; 150 return (E)elementData[cursor++]; 151 } 152 153 //删除游标左面元素,执行完next后只能执行一次 154 @Override 155 public void remove() { 156 if(lastRet<0) { 157 try { 158 throw new MyException(); 159 } catch (MyException e) { 160 e.printremove(); 161 } 162 } 163 System.arraycopy(elementData,lastRet+1,elementData,lastRet,size-lastRet-1); 164 cursor = lastRet; 165 lastRet = -1; 166 elementData[--size] = null; 167 } 168 } 169 170 public static void main(String[] args) { 171 MyArrayList<String> list = new MyArrayList<String>(); 172 list.add("aaa"); 173 list.add("bbb"); 174 list.add("ccc"); 175 list.add(2,"123"); 176 list.remove("ccc"); 177 //使用迭代器遍历 178 for(Iterator<String> itr=list.iterator();itr.hasNext();) { 179 System.out.println(itr.next()); 180 //itr.remove(); 181 } 182 183 System.out.println("---------------------"); 184 185 //使用增强for循环遍历 186 for(String str:list){ 187 System.out.println(str); 188 } 189 } 190 }
1 package ArraryList; 2 3 public class MyException extends Exception{ 4 5 private static final long serialVersionUID = 1L; 6 7 public MyException() { 8 System.out.print("出现异常:"); 9 } 10 11 public void printIndex() { 12 System.out.println("索引范围越界!"); 13 System.exit(1); 14 } 15 16 public void printInit(){ 17 System.out.println("请重新初始化"); 18 } 19 20 public void printnext() { 21 System.out.println("游标越界!"); 22 System.exit(1); 23 } 24 25 public void printremove() { 26 System.out.println("remove()只有在执行完next()后才能且只能执行一次!"); 27 System.exit(1); 28 } 29 }
以上是关于手写ArrayList的主要内容,如果未能解决你的问题,请参考以下文章