public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable
继承AbstractList,实现List<E>, RandomAccess, Cloneable, java.io.Serializable
- ArrayList是List接口的可调整数组实现。实现所有可选的列表操作,并允许所有元素,包括null。除了实现List接口之外,该类还提供了操作内部用于存储列表的数组大小的方法。(这个类大致相当于Vector,只是它是非同步的。)
- 每个ArrayList实例都有一个容量。capacity是用于存储列表中元素的数组的大小。它总是至少和列表大小一样大。当元素被添加到ArrayList中时,它的容量会自动增长。
- 我们可以在使用ensureCapacity操作添加大量元素之前增加ArrayList实例的容量。这可能会减少增量重新分配的数量
- 它不是同步的,要同步的话可以 List list = Collections.synchronizedList(new List());
- 如果在创建迭代器之后的任何时间,列表的结构被修改,除了通过迭代器自己的remove或add方法,迭代器将抛出ConcurrentModificationException。
@Test
public void test3(){
List list = new ArrayList();
list.add("慧宝贝");
list.add("肖路遥");
Iterator iterator = list.iterator();
list.remove("肖路遥");
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
构造器
(1)指定初始容量,在开发中,知道需要的大致容量后,避免多次增容,减小开销,建议用此构造器。
public ArrayList(int initialCapacity) {//initialCapacity 传入的初始数组容量
if (initialCapacity > 0) {//当初始容量 >0 时,new一个大小为初始容量的数组
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {//当初始容量==0时,new一个空数组
this.elementData = EMPTY_ELEMENTDATA;
} else {//否则抛出异常
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
(2)
//空参构造器,new一个空数组
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
(3)
//new一个传入参数是集合的新对象
public ArrayList(Collection<? extends E> c) {
Object[] a = c.toArray();//将c转化为数组然后赋给a
if ((size = a.length) != 0) {//若长度不为0
if (c.getClass() == ArrayList.class) {//若是同类,直接赋给elementData
elementData = a;
} else {//如不是,拷贝所有元素再赋给elementData
elementData = Arrays.copyOf(a, size, Object[].class);
}
} else {//如长度为0,直接new一个空对象
// replace with empty array.
elementData = EMPTY_ELEMENTDATA;
}
}
方法:由于ArrayList实现List,List实现Collection,所以这两者的方法都可以用
自己的方法:
- trimTosize() 将这个ArrayList实例的容量削减为列表的当前大小。应用程序可以使用此操作来最小化ArrayList实例的存储。
- ensureCapacity()增加这个ArrayList实例的容量
/**
* 默认初始容量.
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 用于空实例的空数组实例。如 ArrayList list = new ArrayList<>() list就等于{}.
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public void ensureCapacity(int minCapacity) {
//判断需要扩容的数组是否为空实例(空数组)如果为不为空,则变量等于0.为空则变量等于数组默认容量 10
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
? 0
: DEFAULT_CAPACITY;
//如果需要扩容的量大于定义的变量。则进一步调用以下方法。
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
//需要扩容的量大于原数组的长度,则进一步调用方法。(其实这里就本文章对ensureCapacity()
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
//要分配的数组的最大大小
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* 真正扩容的地方
*/
private void grow(int minCapacity) {
int oldCapacity = elementData.length; //原数组的长度
int newCapacity = oldCapacity + (oldCapacity >> 1); //原数组的长度+原数组的长度/2
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity; // 系统给予的扩容策略所扩的容量<用户给的扩容量,则改用用户指定扩容量
if (newCapacity - MAX_ARRAY_SIZE > 0)
// 如果需要扩容的量大于了本类中定义的最大扩容限制,则扩容到 int 类型最大长度
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);// 扩容,其实调用的的是数组的复制方法
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0)
throw new OutOfMemoryError();
// 如若需要扩容的量大于了最大限制,则扩容量改为 int 最大限制量:2147483647。否则为本类中所限制长度:2147483647-8
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
扩容策略:
1、系统的默认扩容是扩容为原数组长度的1.5倍
2、若用户设置的扩容量大于默认扩容量,就使用用户的,否则还是系统默认的
3、若新的容量大于设置的最大扩容限制,那么就扩容到 int 类型的最大长度,否则最多扩容到本类中所限制的长度。
其他方法
size()返回此list的元素个数
@Test
public void test4(){
List list = new ArrayList();
list.add("王慧");
System.out.println(list.size());//返回1
}
isEmpy() 判断是否为空
@Test
public void test5(){
List list = new ArrayList();
list.add("王慧");
System.out.println(list.isEmpty());//false
}
contains(Object o) 判断是否包含0
@Test
public void test6(){
List list = new ArrayList();
list.add("王慧");
boolean contains = list.contains("王慧");
System.out.println(contains);//true
}
indexOf(Object o) 返回该元素的索引位置
@Test
public void test7(){
List list = new ArrayList();
list.add("王慧");
int indexOf = list.indexOf("王慧");
System.out.println(indexOf);//0
}
lastIndexOf(Object o) 返回这个元素的最后一个索引位置
@Test
public void test8() {
List list = new ArrayList();
list.add("王慧");
list.add("肖路遥");
list.add("王慧");
int lastIndexOf = list.lastIndexOf("王慧");
System.out.println(lastIndexOf);//2
}
clone() 返回这个ArrayList实例的浅拷贝。(元素本身不会被复制。) 返回:这个ArrayList实例的克隆
toArray() 转化为数组
@Test
public void test9(){
List list = new ArrayList();
list.add("王慧");
Object[] array = list.toArray();
System.out.println(Arrays.toString(array)); //[王慧]
}
get()
@Test
public void test10(){
List list = new ArrayList();
list.add("王慧");
Object o = list.get(0);
System.out.println(o);//王慧
}
set(int index, E element) 更改索引为index的元素为element
@Test
public void test11(){
List list = new ArrayList();
list.add("王慧");
list.set(0,"肖路遥");
System.out.println(list);//肖路遥
}
remove(int index) 移除指定索引位置index的元素
@Test
public void test12(){
List list = new ArrayList();
list.add("王慧");
list.remove(0);
System.out.println(list);//[]
}