阅读ArrayList源码后, 决定自己编写一个相似的类,以熟悉ArrayList集合
特别注意 :
- ArrayList集合中的成员变量 size与elementData.length区别,这也是为什么ArrayList给我们一种动态的感觉
- size是ArrayList类对象当前elementData中所含有的元素个数, 而elementData.length是底层分配的数组的长度(默认该长度是10)
- ArrayList中的迭代器是内部类实现Iterator<E>接口
- ArrayList中的扩容是理解该类的关键(第一次调用add方法的时候, minCapacity为10, 相当于(E) new Object[10] 之后将原数组数据复制过去)
以下附上代码 (只实现了iterator, add, toSting)JDK1.8 :
1 package utils; 2 3 4 import java.util.Iterator; 5 import java.util.function.Consumer; 6 7 public class TaoArrayList2<E> { 8 9 private static final Object[] DEFAULTARRAY = {}; //默认示例数组 10 private static final int DEFAULTARRAYSIZE = 10; //数组默认大小 11 private int modCount = 0; 12 private static final int maxSize = 2147483647; //2^31-1 13 private Object[] elementData; 14 private int size; 15 16 public TaoArrayList2(){ 17 elementData = DEFAULTARRAY; 18 } 19 20 public boolean add(E e){ 21 ensureCapacity(size + 1); 22 elementData[size++] = e; 23 return true; 24 } 25 26 private void ensureCapacity(int minCapacity){ 27 ensureExplicitCapacity(calcuteCapcity(elementData, minCapacity)); 28 } 29 30 private void ensureExplicitCapacity(int minCapacity){ 31 modCount++; 32 if (minCapacity - elementData.length > 0){ 33 grow(minCapacity); 34 } 35 } 36 37 private void grow(int minCapacity){ 38 int oldLength = elementData.length; 39 int newLength = oldLength + ( oldLength>>1 ); 40 if (newLength - minCapacity < 0){ 41 newLength = minCapacity; 42 } 43 if (newLength - maxSize > 0){ 44 newLength = maxSize; 45 } 46 //根据newLength重新创建数组, 进行复制 47 elementData = cope(elementData, newLength); 48 } 49 50 private Object[] cope(Object[] elementData, int length){ 51 Object[] returnArray = new Object[length]; 52 for(int i = 0; i < elementData.length; i++){ 53 returnArray[i] = elementData[i]; 54 } 55 return returnArray; 56 } 57 58 private int calcuteCapcity(Object[] elementData, int minCapacity){ 59 if (elementData == DEFAULTARRAY){ 60 return Math.max(DEFAULTARRAYSIZE, minCapacity); 61 } 62 return minCapacity; 63 } 64 65 @Override 66 public String toString() { 67 Iterator iterator = new MyItr(); //自己定义的当前类的迭代器. 68 StringBuffer sb = new StringBuffer(); 69 if (elementData.length == 0){ 70 return "[]"; 71 } 72 sb.append("["); 73 while (iterator.hasNext()){ 74 if (((MyItr) iterator).isLast()){ 75 sb.append(iterator.next()); 76 }else { 77 sb.append(iterator.next()+","); 78 } 79 80 } 81 sb.append("]"); 82 return sb.toString(); 83 } 84 85 public Iterator<E> myIterator(){ 86 return new MyItr<E>(); 87 } 88 89 private class MyItr<E> implements Iterator<E>{ 90 int cursor; 91 MyItr(){ 92 } 93 @Override 94 public boolean hasNext() { 95 return (cursor != (TaoArrayList2.this.size)); 96 } 97 98 @Override 99 public E next() { 100 if (cursor >= TaoArrayList2.this.size){ 101 throw new RuntimeException("光标错误,超出size"); 102 } 103 Object[] elementData = TaoArrayList2.this.elementData; 104 if (cursor >= elementData.length) { 105 throw new RuntimeException("数组光标超出数组长度"); 106 } 107 return (E) elementData[cursor++]; 108 } 109 110 public boolean isLast(){ 111 return ( cursor == (TaoArrayList2.this.size-1) ) ? true : false; 112 } 113 114 @Override 115 public void remove() { 116 117 } 118 119 @Override 120 public void forEachRemaining(Consumer<? super E> action) { 121 122 } 123 } 124 }