List集合
常用方法
注意这是List集合独有的方法,并且一旦涉及到范围(比如subList方法),总是左闭右开的。
List不能单独声明,需要用到List的实现子类。
List a = new ArrayList();
List b = new LinkedList();
List c = new Vector();
注意事项
1. ArrayList 可以加入多个null。
2. ArrayList 是由数组来实现数据存储的。
3. ArrayList 基本等同于Vector,但ArrayList是线程不安全的(没有synchronized),在多线程情况下,不建议使用ArrayList。
ArrayList底层结构
1. ArrayList 中维护了一个Object类型的数组elementData。
trannsient Object[] elementData; // transient 表示瞬间,短暂的,表示该属性不会被序列化
2. 当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第一次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1.5倍。
3. 如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData为1.5倍。
ArrayList底层源码
如果数组为初始分配数组,那么就返回最小需求容量和10之间的最大值(注意有初始化参数的并不是DEFAULTCAPACITY...这个数组)。否则返回最小需求容量。
1. modCount 记录集合被修改的次数 2. 如果elementData的大小不够(目前的长度小于最小需求容量),就调用grow方法去扩容。
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length; //原先数组的长度
int newCapacity = oldCapacity + (oldCapacity >> 1);
// >>1表示/2,把原数组长度*1.5,赋给newCapacity
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//针对第一次,newCapacity为0(0 + 0*0.5),此时minCapacity为10
if (newCapacity - MAX_ARRAY_SIZE > 0)
//如果超过了系统最大容量,用hugeCapacity判断
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
//用Arrays类的copyOf方法(空余位置为null)
}
扩容后Debug时看不到数组的null?把 Hide null elements in arrays and collections 和 Enable alternative view for Collections classes去掉。
Vector
基本介绍
ArrayList和Vector比较
LinkedList
注:LinkedList维护的双向链表没有头结点,第一个就是首元结点。remove方法默认删除第一个结点。里面的元素是LinkedList类里定义的Node。
遍历方法有:迭代器,增强for与普通for循环。
public static void main(String[] args) {
LinkedList a = new LinkedList();
Iterator iterator= a.iterator();
while (iterator.hasNext()) { //迭代器
Object next = iterator.next();
...;
}
for (Object o : a) { //增强for
...;
}
for(int i = 0;i<a.size();i++){ //普通for循环
...;
}
}
初始化源码:
void linkLast(E e) {
final Node<E> l = last; //保存尾指针
final Node<E> newNode = new Node<>(l, e, null);
//三个参数分别对应prior,data,next
last = newNode; //更新尾指针
if (l == null)
first = newNode; //如果原先尾指针为null,说明newNode为第一个结点,修改first
else
l.next = newNode; //否则把新结点接在最后一个结点后面
size++;
modCount++;
}