不是线程安全的
主要方法:
ArrayList arr = new ArrayList();
arr.add():添加元素
arr.size():获取集合大小
arr.get():根据下标获取集合对应的元素
arr.isEmpty():返回 size 是否为0
arr.iterator(): 迭代器
arr.clear(): 清除所有集合元素
arr.toArray():将集合转换是 Object[] 数组
arr.remove : 移除元素(根据下标 或 元素)
arr.contains():是否包含元素
arr.indexOf():返回元素的索引,不存在此元素返回 -1
arr.lastIndexO():f某个元素最后一次出现的索引位置的值
arr.subList(fromIndex, toIndex):根据索引截取List
arr.trimToSize();
去掉预留元素位置 ,ArrayList 自动扩容为1.5倍 当ArrayList 存储10个元素时,所占用的内存空间已经达到15个,trimToSize() 用来删除多余的内存。
/**
* 默认初始容量 默认大小 为 10
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 空的对象数组
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* 无参构造函数创建的数组 默认容量 10
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/*** 存放缓存数据的数组*/
transient Object[] elementData;
/**集合元素的数量*/
private int size;
带有初始容量的构造方法
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {//判断初始容量是否为 0
this.elementData = new Object[initialCapacity];//不为 0 直接 new 一个 initialCapacity 大小的数组赋值给 elementData
} else if (initialCapacity == 0) {//初始容量为 0
this.elementData = EMPTY_ELEMENTDATA;//elementData 为空的数组(默认容量 0)
} else {//小于 0 抛出参数不合法异常
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
/* 无参构造函数 默认容量 10*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
方法
trimToSize()
public void trimToSize() {
modCount++;//记录集合修改的次数,此变量来检验在迭代过程中集合是否被修改,如果修改了就抛出异常
if (size < elementData.length) {//length是集合申请的内容空间长度;size是集合的元素个数
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}
add()
public boolean add(E e) {//集合添加元素
ensureCapacityInternal(size + 1);//扩容
elementData[size++] = e;//将值e赋给elementData 的 size + 1 的位置
return true;
}
private void ensureCapacityInternal(int minCapacity) {//扩容
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//数组是否有默认长度(10)
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);//默认容量长度 与当前 元素数量对比 取出最大的值
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;//记录集合修改的次数
// overflow-conscious code
if (minCapacity - elementData.length > 0)//当前元素数量 是否大于 数组容量
grow(minCapacity);//大于 就进行扩容
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;//当前容量
int newCapacity = oldCapacity + (oldCapacity >> 1);//当前容量的1.5倍扩容
if (newCapacity - minCapacity < 0)//如果扩容以后 还是小于 当前元素数量
newCapacity = minCapacity;//直接将容量 赋值位当前元素的数量
if (newCapacity - MAX_ARRAY_SIZE > 0)//新扩容的容量是否超出数组最大容量
newCapacity = hugeCapacity(minCapacity);//重新进行容量规划
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
@Native public static final int MAX_VALUE = 0x7fffffff;
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
add(int index, E element)
public void add(int index, E element) {
rangeCheckForAdd(index);//判断下标是否越界
ensureCapacityInternal(size + 1); //扩容
//demo:
// public static native void arraycopy(
//Object src, src:源数组--> elementData
//int srcPos, srcPos:源数组要复制的起始位置 --> index
//Object dest, dest:目的数组 --> elementData
//int destPos, destPos:目的数组放置的起始位置 --> index + 1
//int length); length:复制的长度 --> size - index
System.arraycopy(elementData, index, elementData, index + 1,size - index);
elementData[index] = element;//将值 element 插入 index 下标位置
size++;//数组大小+1
}
/**
* A version of rangeCheck used by add and addAll.
*/
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)//判断下标是否 大于 数组长度 or 是否小于0
throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); //抛出下标越界异常
}
remove(int index)
public E remove(int index) {
rangeCheck(index);//检查index是否大于size
modCount++;//记录集合变动次数
E oldValue = elementData(index);//获取值
int numMoved = size - index - 1;//复制的长度
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
//最后的一位下标的值 赋值为 null 交给GC进行垃圾处理
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
帮助理解demo
String [] c = {"1","3","5","7"};
int size = c.length;
System.arraycopy(c,2,c,1,2);
c[--size]=null;
for(String d : c){
System.out.println(d+"************");
}
输出结果
1************
5************
7************
null************//这个没懂,应该是java的垃圾回收会自动处理
remove(Object o)
public boolean remove(Object o) {
if (o == null) {//移除对象 为 null
for (int index = 0; index < size; index++)//循环数组
if (elementData[index] == null) {//获取 需要移除对象的 下标
fastRemove(index);//根据下标进行删除
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
/*
* Private remove method that skips bounds checking and does not
* return the value removed.
*/
private void fastRemove(int index) {// 同 remove(int index)
modCount++;
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
}
clear()
public void clear() {
modCount++;//记录集合修改次数
// clear to let GC do its work 清除让GC做它的工作
for (int i = 0; i < size; i++)//循环数组
elementData[i] = null;//赋值为 null
size = 0;//数组大小 置空
}