/** * The maximum size of array to allocate. * Some VMs reserve some header words in an array. * Attempts to allocate larger arrays may result in * OutOfMemoryError: Requested array size exceeds VM limit * 数组作为一个对象,需要一定的内存存储对象头信息,对象头信息最大占用内存不可超过8字节 */ privatestaticfinalint MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
publicvoidensureCapacity(int minCapacity){ // 如果elementData是默认的空数组,minExpand为10,否则为0 int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) // any size if not default element table ? 0 // larger than default for default empty table. It's already // supposed to be at default size. : DEFAULT_CAPACITY; // 如果设定容量大于minExpand,则执行扩容 if (minCapacity > minExpand) { ensureExplicitCapacity(minCapacity); } }
privatevoidfastRemove(int index){ // 结构性修改计数器+1 modCount++; // 因为去除一个数据,所以该位置后的数据均要前移一位 int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); // 数据末尾设为空,GC垃圾回收 elementData[--size] = null; // clear to let GC do its work }
forEach
1.8后,ArrayList支持函数式编程、Lambda表达式
1 2 3 4 5 6 7 8 9 10 11 12 13 14
@Override publicvoidforEach(Consumer<? super E> action){ Objects.requireNonNull(action); finalint expectedModCount = modCount; @SuppressWarnings("unchecked") final E[] elementData = (E[]) this.elementData; finalint size = this.size; for (int i=0; modCount == expectedModCount && i < size; i++) { action.accept(elementData[i]); } if (modCount != expectedModCount) { thrownew ConcurrentModificationException(); } }
Lambda遍历输出list集合
1 2
ArrayList<String> list = new ArrayList<>(); list.forEach(x -> System.out.print(x));
get
1 2 3 4 5 6
public E get(int index){ // 检查下标是否合法 rangeCheck(index); // 返回指定下标值 return elementData(index); }
publicintindexOf(Object o){ if (o == null) { for (int i = 0; i < size; i++) if (elementData[i]==null) return i; } else { for (int i = 0; i < size; i++) if (o.equals(elementData[i])) return i; } return -1; }
isEmpty
判断集合是否为空
1 2 3
publicbooleanisEmpty(){ return size == 0; }
iterator
返回Iterator迭代器
1 2 3
public Iterator<E> iterator(){ returnnew Itr(); }
lastIndexOf
同indexOf,返回数组中指定元素出现的最后一个位置
1 2 3 4 5 6 7 8 9 10 11 12
publicintlastIndexOf(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; }
listIterator
返回ListIterator迭代器
1 2 3
public ListIterator<E> listIterator(){ returnnew ListItr(0); }
listIterator
返回L从指定位置开始的ListIterator迭代器
1 2 3 4 5
public ListIterator<E> listIterator(int index){ if (index < 0 || index > size) thrownew IndexOutOfBoundsException("Index: "+index); returnnew ListItr(index); }
// Read in size, and any hidden stuff s.defaultReadObject();
// Read in capacity s.readInt(); // ignored
if (size > 0) { // be like clone(), allocate array based upon size not capacity int capacity = calculateCapacity(elementData, size); SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, capacity); ensureCapacityInternal(size);
Object[] a = elementData; // Read in all elements in the proper order. for (int i=0; i<size; i++) { a[i] = s.readObject(); } } }
remove
remove(int index)方法的作用是删除指定下标的元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
public E remove(int index){ // 判断下标合法性 rangeCheck(index); // 结构性修改计数器+1 modCount++; // 获取旧值 E oldValue = elementData(index); // 将指定下标后面一位到数组末尾的全部元素向前移动一个单位,并且把数组最后一个元素设置为null,需要移动的元素个数为:size-index-1。 int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work // 返回旧值 return oldValue; }
删除指定元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
publicbooleanremove(Object o){ if (o == null) { for (int index = 0; index < size; index++) if (elementData[index] == null) { fastRemove(index); returntrue; } } else { for (int index = 0; index < size; index++) if (o.equals(elementData[index])) { fastRemove(index); returntrue; } } returnfalse; }
public Object[]toArray() { return Arrays.copyOf(elementData, size); }
第二个方法转为与传入参数类型相同的数组
1 2 3 4 5 6 7 8 9 10
@SuppressWarnings("unchecked") public <T> T[]toArray(T[] a) { if (a.length < size) // Make a new array of a's runtime type, but my contents: return (T[]) Arrays.copyOf(elementData, size, a.getClass()); System.arraycopy(elementData, 0, a, 0, size); if (a.length > size) a[size] = null; return a; }
privatevoidwriteObject(java.io.ObjectOutputStream s) throws java.io.IOException{ // Write out element count, and any hidden stuff int expectedModCount = modCount; s.defaultWriteObject();
// Write out size as capacity for behavioural compatibility with clone() s.writeInt(size);
// 注意这里,elementData长度为length,大小为size,还有length-size个null数据,序列化时只输出size个数据,null数据不输出,避免资源浪费 for (int i=0; i<size; i++) { s.writeObject(elementData[i]); }
if (modCount != expectedModCount) { thrownew ConcurrentModificationException(); } }