写在前面的话:读书破万卷,编码如有神
--------------------------------------------------------------------
下文主要对 java.util.ArrayList<E> 进行整体性介绍,主要内容包括:
1、 ArrayList 概述
2、 ArrayList 中的属性、构造方法、常用方法介绍
3、 ArrayList 遍历
参考内容:
1、JDK 源码 (1.7)
--------------------------------------------------------------------
1. ArrayList 概述
java.util.ArrayList<E> 是一个什么玩意,它有什么功能,我们拿 ArrayList 能够干嘛
简单点说:java.util.ArrayList<E> 是一个列表类,它是用来存放其他 Java 对象,内部是通过数组来实现的。
先看下面的图 (简略图):
(1)java.util.ArrayList
(2)java.util.ArrayList<E> 内部是通过数组来实现的:
当数组容量不够的时候,会对数组容量进行扩容
可以通过数组下标来快速的访问 ArrayList 里面的元素
当新增或者删除 ArrayList 里面的元素时,可能会涉及到移位操作
可以截取数组的子数组操作
java.util.ArrayList<E> 的定义如下:
- 1 public class ArrayList extends AbstractList
- 2 implements List, RandomAccess, Cloneable, java.io.Serializable{
- 3 //fields
- 4
- 5 //constructor
- 6
- 7 //methods
- 8
- 9 //inner class 'Itr'
- 10
- 11 //inner class 'ListItr'
- 12
- 13 //inner class 'SubList'
- 14 }
从 ArrayList 类的定义中可以看到,它好复杂哟, 定义了那么多的东西,又有父类,又实现了接口等等,这都要怪它的'祖宗', 定义了那么多的规范、规则。(@_@)
好了,不多废话,撸起袖子继续干:
下面来看看一副图:
2. ArrayList 中的属性、构造方法、常用方法介绍
先来对 java.util.ArrayList<E> 的描述进行一些约定:
下面文中的:
'列表'代表 ArrayList 内部的 Object[] elementData 数组
'列表大小'代表 ArrayList 内部的 Object[] elementData 数组的长度
'元素'代表往 ArrayList 中添加的 Java 对象
2.1 java.util.ArrayList<E> 的常见属性
- 1 //序列号
- 2 private static final long serialVersionUID = 8683452581122892189L;
- 3 //ArrayList实际存储元素的地方
- 4 private transient Object[] elementData;
- 5 //ArrayList中存储的元素个数
- 6 private int size;
- 7 //ArrayList最多存储元素的个数
- 8 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
- 9 //fast-fail失败机制标记
- 10 protected transient int modCount = 0;
2.2 java.util.ArrayList<E> 的构造方法
第一种:默认构造方法(无参数构造方法)
- 1 public ArrayList()
第二种: 带初始列表容量大小参数的构造方法
- 1 public ArrayList(int initialCapacity)
第三种: 带初始化子列表参数的构造方法
- 1 public ArrayList(Collectionextends E> c)
2.3 java.util.ArrayList<E> 的常用方法
修改操作 | boolean add(E e) | 将指定的元素添加到此列表的尾部 |
void add(int index,E element) | 将指定的元素插入此列表中的指定位置 | |
E remove(int index) | 移除此列表中指定位置上的元素 | |
boolean remove(Object o) | 移除此列表中首次出现的指定元素 | |
E set(int index,E element) | 用指定的元素替代此列表中指定位置上的元素 | |
批量操作 | boolean addAll(Collection<? extends E> c) | 将子集合 c 中的元素添加到此集合中 |
boolean addAll(int index,Collection<? extends E> c) | 将子集合 c 中的元素添加到此集合中的 index 位置开始处 | |
void clear() | 清空此集合 | |
protected void removeRange(int fromIndex,int toIndex) | 移除集合中索引在 fromIndex(包括) 和 toIndex(不包括) 之间的所有元素 | |
public boolean removeAll(Collection<?> c) | 移除此 collection 中那些也包含在指定 collection 中的所有元素 | |
public boolean retainAll(Collection<?> c) | 仅保留在子集合 c 中那些也包含在此集合中的元素 | |
查询操作 | boolean contains(Object o) | 判断集合中是否包含了元素 o |
E get(int index) | 返回此集合中 index 位置上的元素 | |
int indexOf(Object o) | 返回此集合中首次出现元素 o 的位置 | |
boolean isEmpty() | 判断此集合是否为空 | |
int lastIndexOf(Object o) | 返回此集合中最后一次出现元素 o 的位置 | |
int size() | 返回此集合中元素的个数 | |
其他操作 | Object clone() | 返回此列表实例的浅复制 |
void ensureCapaCity(int minCapacity) | 如有必要, 增加此列表实例的容量, 以确保它至少能够容纳最小容量参数所指定的元素数 | |
void trimToSize() | 将此列表实例的容量调整为列表的当前大小 | |
数组操作 | Object[] toArray() | 按适当顺序返回包含此列表中所有元素的数组 |
<T> T[] toArray(T[] a) | 按适当顺序返回包含此列表中所有元素的数组 | |
Iterator 和子 List 操作 | ListIterator<E> listIterator(int index) | 返回列表的 ListIterator 实例 |
ListIterator<E> listIterator() | 返回列表的 ListIterator 实例 | |
Iterator<E> iterator() | 返回列表的 Iterator 实例 | |
List<E> subList(int fromIndex, int toIndex) | 返回列表的子列表 |
----------------------------------------------------------------------------------------
3. ArrayList 遍历方法
java.util.ArrayList<E> 支持三种遍历方式:
第一种: 通过索引值去遍历(随机遍历)
第三种: 通过增强的 for 循环去遍历
第三种: 通过迭代器去遍历
下面就来看看三种遍历方式的示例代码和遍历的效率比较:
View Code
- 1 import java.util.ArrayList;
- 2 import java.util.Iterator;
- 3 import java.util.List;
- 4
- 5
- 6 public class ArrayListAccessDemo {
- 7 /**
- 8 * 通过索引值去遍历(随机访问)
- 9 */
- 10 public static void accessByIndex(List list){
- 11 long beginTime = System.currentTimeMillis();
- 12 for(int i = 0;i < list.size();i++){
- 13 list.get(i);
- 14 }
- 15 long endTime = System.currentTimeMillis();
- 16 long totalTime = endTime - beginTime;
- 17 System.out.println("通过索引值去遍历(随机访问) 花费的时间:" + totalTime+" 毫秒");
- 18
- 19 }
- 20
- 21 /**
- 22 * 通过增强的for循环去遍历
- 23 */
- 24 public static void accessByFor(List list){
- 25 long beginTime = System.currentTimeMillis();
- 26 for(Integer i : list){
- 27 list.get(i);
- 28 }
- 29 long endTime = System.currentTimeMillis();
- 30 long totalTime = endTime - beginTime;
- 31 System.out.println("通过增强的for循环去遍历 花费的时间:" + totalTime+" 毫秒");
- 32
- 33 }
- 34
- 35 /**
- 36 * 通过Iterator迭代器去遍历
- 37 */
- 38 public static void accessByIterator(List list){
- 39 long beginTime = System.currentTimeMillis();
- 40 Iterator it = list.iterator();
- 41 while(it.hasNext()){
- 42 it.next();
- 43 }
- 44 long endTime = System.currentTimeMillis();
- 45 long totalTime = endTime - beginTime;
- 46 System.out.println("通过Iterator迭代器去遍历 花费的时间:" + totalTime+" 毫秒");
- 47
- 48 }
- 49
- 50 public static void main(String[] args) {
- 51 //创建一个ArrayList实例
- 52 List list = new ArrayList();
- 53 //往ArrayList实例中添加数据
- 54 for(int i = 0;i < 10000000;i++){
- 55 list.add(i);
- 56 }
- 57
- 58 accessByIndex(list);
- 59 accessByFor(list);
- 60 accessByIterator(list);
- 61 }
- 62 }
- 63
- 64 运行结果:
- 65 ArrayList中有100W条数据时:
- 66 通过索引值去遍历(随机访问) 花费的时间:2 毫秒
- 67 通过增强的for循环去遍历 花费的时间:9 毫秒
- 68 通过Iterator迭代器去遍历 花费的时间:4 毫秒
- 69
- 70 ArrayList中有500W条数据时:
- 71 通过索引值去遍历(随机访问) 花费的时间:4 毫秒
- 72 通过增强的for循环去遍历 花费的时间:20 毫秒
- 73 通过Iterator迭代器去遍历 花费的时间:9 毫秒
- 74
- 75 ArrayList中有1000W条数据时:
- 76 通过索引值去遍历(随机访问) 花费的时间:3 毫秒
- 77 通过增强的for循环去遍历 花费的时间:32 毫秒
- 78 通过Iterator迭代器去遍历 花费的时间:13 毫秒
- 79
- 80 ArrayList中有5000W条数据时:
- 81 通过索引值去遍历(随机访问) 花费的时间:3 毫秒
- 82 通过增强的for循环去遍历 花费的时间:118 毫秒
- 83 通过Iterator迭代器去遍历 花费的时间:55 毫秒
----------------------------------------------------------------------------------------
来源: