ArrayList简介:
java.util.ArrayList 是我们最常用的一个类,ArrayList 底层是动态数组,读者可以把它理解为数组的实现
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{ }
如上代码我们可以看到 ArrayList 继承了 AbstractList() 抽象类,并实现了 List, RandomAccess, Cloneable, Serializable 接口
AbstractList :
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>{}
可以看到AbstractList 继承了 AbstractCollection 接口, 并实现了List 接口
AbstractCollection :
public abstract class AbstractCollection<E> implements Collection<E>{}
AbstractCollection 是一个抽象类,实现了Collection 接口,并提供了某些方法的具体实现。
Collection:
Collection 是一个顶级接口,是很多集合类的顶级接口,继承了Iterable ,支持轻量级遍历其中元素
public interface Collection<E> extends Iterable<E>{}
List :
ArrayList 实现了List接口,List 也是一个和Collection 媲美的顶级接口,继承了Collection 接口
public interface List<E> extends Collection<E>{}
它是许多集合类的父类,
eg:
List list = new ArrayList();
List list2 = new LinkedList();
RandomAccess
RandomAccess 也是一个顶级接口,实现了此接口的类支持随机访问
Cloneable
Cloneable 接口是一个顶级接口,实现了此接口的类支持浅拷贝
Serializable
实现此接口的类支持序列化的功能
ArrayList 相关方法介绍
trimToSize()
代码表示
实践才是检验真理最好的方式:
importjava.util.*;
/**
* 详述ArrayList 基本用法
*/
public class ArrayListTest{
private static class SortList implements Comparator<String>{
@Override
public int compare(String o1, String o2) {
Integeri1=Integer.valueOf(o1);
Integeri2=Integer.valueOf(o2);
if(i1<i2){
return-1;
}elseif(i1==i2){
return0;
}
return1;
}
}
// 使用可变参数,能够接受任意个参数
public Set<String> putSet(String...args){
Set<String> sets = new HashSet<>();
for(String str: args){
sets.add(str);
}
return sets;
}
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("111");
list.add("222");
// 在指定位置添加元素
list.add(0,"333");
System.out.println(list);
// 进行外部排序
list.sort(newSortList());
System.out.println(list);
list.clear();
System.out.println(list.size());
// 使用addAll添加元素
ArrayList Testat = newArrayListTest();
list.addAll(at.putSet("1","2","3"));
Iterator<String> it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
// 移除所有元素
it.remove();
}
System.out.println("list是否为空 ? "+list.isEmpty());
list.add("111");
// 在指定位置添加一个set集合
list.addAll(0,at.putSet("1","2","3"));
System.out.println(list);
// 是否包含指定元素
if(list.contains("111")) {
list.remove("111");
}
System.out.println(list);
System.out.println(list.indexOf("1"));
// 注意subList()这个方法是左开右闭区间,Java 中很多都是类似的
System.out.println(list.subList(0,3));
// 扩大list的容量
list.ensureCapacity(10);
// 去掉list空闲的容量
list.trimToSize();
// 获取某个特定的元素
System.out.println(list.get(1));
// 创建一个list的双向链表
ListIterator<String> listIterator = list.listIterator();
while(listIterator.hasNext()){
// 移到list的末端
System.out.println(listIterator.next());
}
System.out.println("--------------------------");
while(listIterator.hasPrevious()){
// 移到list的首端
System.out.println(listIterator.previous());
}
// 把list转换为数组
Object[] objects = list.toArray();
System.out.println("objects = "+objects);
}
}
相关方法源码分析
分析源码还是要有代码的实例,跟进去理解每一行的意思,俗话说,有debug,不求人!
add()方法
/**
* Appends the specified element to the end of this list.
* 添加指定的元素在list的末尾
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
// 假设第一次添加的是 "111"
public boolean add(E e) {
// size是0,所以size + 1 传的是1
ensureCapacityInternal(size+1); // Increments modCount!!
// elementData[0] = 111 , size++ = 1
elementData[size++] =e;
returntrue;
}
// 此方法用来进行list 扩容
private void ensureCapacityInternal(int minCapacity) {
// 此时elementData 并没有存储元素,为0
if(elementData==DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
// 则minCapacity 取默认初始容量和minCapacity 的最大值 (取1 和 10的最大值)
minCapacity=Math.max(DEFAULT_CAPACITY, minCapacity);
}
// 确保清晰的容量(最小容量与List元素的比较)
ensureExplicitCapacity(minCapacity);
}
// 在list中添加了一个元素,所以会导致结构化的修改,"结构化的修改"见下面解释
// 此时minCapacity 为 10
private void ensureExplicitCapacity(int minCapacity) {
// 次数 + 1
// 这个列表被修改结构的次数(比如添加和删除元素)会用modCount表示. 结构化修改是指的是能够
// 改变列表容量的操作,或者其他方式改变它,导致遍历的过程会产生错误的结果。
modCount++;
// overflow-conscious code
// 10 - 0 > 0 走grow 方法
if(minCapacity-elementData.length>0)
grow(minCapacity);
}
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
* 增加容量确保容纳足够的元素
*
* @param minCapacity the desired minimum capacity
* 参数传过来的是10
*/
private void grow(int minCapacity) {
// overflow-conscious code
// oldCapacity = 0
intoldCapacity=elementData.length;
// newCapacity = 0
intnewCapacity=oldCapacity+(oldCapacity>>1);
// newCapacity - minCapacity = -10
if(newCapacity-minCapacity<0)
// newCapacity = 10
newCapacity=minCapacity;
// MAX_ARRAY_SIZE = 数组分配的最大空间 = 2147483639
// 一般情况下不会比 MAX_ARRAY_SIZE 还要大
if(newCapacity-MAX_ARRAY_SIZE>0)
newCapacity=hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
// 底层还是用的System.arraycopy(), 关于System.arrayCopy() 读者可以参考我的另一篇博客
elementData=Arrays.copyOf(elementData, newCapacity);
}
输出:
[333, 111, 222]
[111, 222, 333]
0
1
2
3
list是否为空 ? true
[1, 2, 3, 111]
[1, 2, 3]
0
[1, 2, 3]
2
1
2
3
--------------------------
3
2
1
objects = [Ljava.lang.Object;@6e8cf4c6
相关常用的基本数据类型包装类的值: Java基本数据类型包装类常用的值
add(int index, E element)
</div>