List
List集合类中元素有序(添加取出顺序一致),且可重复
常用方法
//在指定位置添加元素
list.add(1,"jack");
//获取指定位置的元素
list.get(1);
//返回obj在集合中首次出现的位置
list.indexOf("jack");
//返回obj在集合中最后出现的位置
list.lastIndexOf("jack");
//替换index位置的元素
list.set(1,"tom");
//返回子集合,前闭后开
list.subList(0,2);
遍历方式
除了Collection的两种方式,还可以用普通for循环,因为List底层是用数组实现的
for (int i =0; i<list.size(); i++){
System.out.println(list.get(i));
}
ArrayList
- 可以加入null
- 由数组实现数据存储的
- ArrayList基本等同于Vector,但是ArrayList是线程不安全的,
ArrayList源码分析
结论
- ArrayList中维护的是一个Object数组elementData
- 创建ArrayList对象时,若使用的是无参构造,则elementData的容量为0,第一次添加,扩容为10,若要再次扩容,则扩容1.5倍
- 若使用指定大小的构造器,扩容时直接扩容1.5倍
源码
public class ArrayList<E>{
//默认仓库容量为10
private static final int DEFAULT_CAPACITY = 10;
//空数组
private static final Object[] EMPTY_ELEMENTDATA = {};
//默认空数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//数据域
transient Object[] elementData;
//当前数组存放元素数量
private int size;
//有参构造,参数为list初始容量
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
//创建一个容量为 形参大小 的数组
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
//若形参大小为0,相当于无参构造,数据域等于空数组
this.elementData = EMPTY_ELEMENTDATA;
} else {
//形参为负数,抛出异常
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
//无参构造
public ArrayList() {
//数据域等于默认的空数组
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
//添加元素
public boolean add(E e) {
ensureCapacityInternal(size + 1); // size+1=当前需要的最小容量
elementData[size++] = e;
return true;
}
//保证容量足够
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
//计算容量
private static int calculateCapacity(Object[] elementData, int minCapacity) {
//如果数据域等于默认的空数组,就说明是无参构造
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
//返回两个数较大的那一个,一般是默认容量10
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
//否则返回当前需要的最小容量
return minCapacity;
}
//检查是否要扩容
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// 如果当前需要的最小容量大于数组容量,也就是说数组放不下了,扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
//扩容
private void grow(int minCapacity) {
// 保存原来容量
int oldCapacity = elementData.length;
//新容量为原来的1.5倍,>>1相当于*2
int newCapacity = oldCapacity + (oldCapacity >> 1);
//如果新容量还是不够,那就让minCapacity为新容量
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//如果新容量超过预设的最大容量,我也不知道干了个啥
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 将数据域数组扩容
elementData = Arrays.copyOf(elementData, newCapacity);
}
}