List接口及其实现类
常用实现类:
List接口特性:
1.有序:自然序列
2.可重复:可以将相同元素存入List中
ArrayList
ArrayList从字面意思上看就可以知道它和数组有关,它又叫可变数组(顾名思义,可以动态增加数组长度)
底层实现原理:
注意:size指的是数组的实际存储元素的个数,capacity是数组的容量
源码分析:
/**
* 默认容量
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* 默认空数组
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* Shared empty array instance used for default sized empty instances. We
* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
* first element is added.
* 用户定义长度为0的数组
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
*调用无参构造方法时候,添加第一个元素时默认初始化容量为10
*
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
*创建一个Collection的ArrayList
*/
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;
}
}
/**
*用户自定义长度
*若用户指定的最小容量 > 最小扩充容量,则以用户指定的为准,否则还是 10
*/
public void ensureCapacity(int minCapacity) {
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
// any size if not default element table
? 0
// larger than default for default empty table. It's already
// supposed to be at default size.
: DEFAULT_CAPACITY;
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
扩容机制
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* 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
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
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);
}
当数组长度与元素长度一样时, int newCapacity = oldCapacity + (oldCapacity >> 1);
原来如果是10,增加之后为10+5=15;
扩容图:
ArrayList常用的API
1.add(E e) 增加一个元素
2.add(int index, E element) 在指定位置增加一个元素
3.addAll(Collection c) 按照指定的顺序,将集合中的元素加入List之中
4.clear() 从列表中删除所有元素。
remove(int index) 删除该列表中指定位置的元素。
remove(Object o) 从列表中删除指定元素的第一个出现(如果存在)。
removeAll(Collection c) 从此列表中删除指定集合中包含的所有元素。
5.set(int index, E element) 用指定的元素替换此列表中指定位置的元素。
6.get(int index) 返回此列表中指定位置的元素。
7.indexOf(Object o) 返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。
8.size() 返回此列表中的元素数。
9.isEmpty() 如果此列表不包含元素,则返回 true
练习代码:
package com.tangbaobao.lambda;
import java.util.ArrayList;
import org.junit.jupiter.engine.discovery.predicates.IsTestFactoryMethod;
/**
* @author 唐学俊
* @version 2017年12月15日下午5:58:32
*
*/
public class Test1 {
public static void main(String[] args) {
//初始化一个ArrayList
ArrayList<Integer> list = new ArrayList<>();
//添加元素
list.add(1);
list.add(3);
list.forEach(x->System.out.print(x));//Lambda表达式遍历
System.out.println();
//在指定位置插入元素
list.add(1, 2);
list.forEach(System.out::print);
System.out.println();
//移除一个元素
list.remove(1);
list.forEach(System.out::print);
System.out.println();
//修改元素
list.set(0, 100);
list.forEach(x->System.out.print(x));
System.out.println();
//移除所有元素
list.clear();
list.forEach(System.out::print);
//打印List的长度以及是否为空
System.out.println("长度:"+list.size());
System.out.println("是否为空:"+list.isEmpty());
}
}