Java集合框架概览之ArrayList源码分析
ArrayList简介
ArrayList是Java集合框架中的一种常用数据结构,它实现了List接口,底层使用数组来存储元素,具有可变长度的特性。ArrayList可以动态地增加或减少元素的个数,无需手动处理数组长度的问题,大大简化了程序的实现。在实际应用中,ArrayList常用于需要频繁读取和修改元素的场景,因为ArrayList的访问速度较快,但插入和删除元素的效率相对较低。
ArrayList源码分析
ArrayList源码主要包含以下几个重要部分:成员变量、构造方法、核心方法和迭代器实现。
成员变量
ArrayList类中有三个重要的成员变量:elementData、size和DEFAULT_CAPACITY。其中,elementData是一个Object类型的数组,用于保存ArrayList中的元素;size表示ArrayList中实际存储的元素数量;DEFAULT_CAPACITY表示默认的初始容量,设定为10。需要注意的是,ArrayList的实际容量(数组长度)并不等于size,后者表示有效元素的个数。
构造方法
ArrayList提供了多个构造方法,常用的有无参构造方法和带初始容量的构造方法。无参构造方法会创建一个默认初始容量为10的ArrayList。带初始容量的构造方法则可以指定一个初始容量,允许根据实际需求进行调整。
/** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } /** * Constructs an empty list with the specified initial capacity. * * @param initialCapacity the initial capacity of the list * @throws IllegalArgumentException if the specified initial capacity is negative */ public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } }
核心方法
ArrayList的核心方法主要包括add、remove、get和set方法。add方法用于向ArrayList中添加元素,在添加前会判断是否需要扩容。remove方法用于移除ArrayList中的元素,并将后续元素向前移位。get方法用于获取指定位置的元素,set方法用于替换指定位置的元素,这两个方法均需要保证索引的有效性。
/** * Appends the specified element to the end of this list. * * @param e element to be appended to this list * @return {@code true} (as specified by {@link Collection#add}) */ public boolean add(E e) { ensureCapacityInternal(size + 1); elementData[size++] = e; return true; } /** * Removes the element at the specified position in this list. * * @param index the index of the element to be removed * @return the element that was removed from the list * @throws IndexOutOfBoundsException {@inheritDoc} */ public E remove(int index) { rangeCheck(index); modCount++; E oldValue = elementData(index); 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; } /** * Returns the element at the specified position in this list. * * @param index index of the element to return * @return the element at the specified position in this list * @throws IndexOutOfBoundsException {@inheritDoc} */ public E get(int index) { rangeCheck(index); return elementData(index); } /** * Replaces the element at the specified position in this list with the * specified element. * * @param index index of the element to replace * @param element element to be stored at the specified position * @return the element previously at the specified position * @throws IndexOutOfBoundsException {@inheritDoc} */ public E set(int index, E element) { rangeCheck(index); E oldValue = elementData(index); elementData[index] = element; return oldValue; }
迭代器实现
ArrayList通过实现Iterator接口来提供遍历功能。ArrayList的迭代器实现是一个内部类Itr,在ArrayList中通过返回Itr对象的实例来实现迭代。Itr类实现了hasNext、next、remove等方法,通过游标cursor和标记lastRet来实现迭代器的功能。
总结
ArrayList是Java集合框架中常用的数据结构之一,底层使用数组来存储元素,具有可变长度的特性。ArrayList通过动态扩容和移动元素实现了动态增加和减少元素的功能。本文对ArrayList的源码进行了分析,介绍了其成员变量、构造方法、核心方法和迭代器实现。掌握ArrayList的源码可以更好地理解其内部实现机制,为使用和优化ArrayList提供指导。在实际开发中,需要注意ArrayList的容量调整和元素访问的效率问题,避免频繁的插入和删除操作。