List
interface Listextends Collection
有序集合 可以精准控制列表中每个元素的位置
方法
继承方法请看 Collection
E get(int index) 返回此列表中指定位置的元素
E set(int index,E element) 用指定的元素替换此列表中指定位置的元素。
E remove(int index) 从列表中删除指定元素的第一个出现(如果存在)
int indexOf(Object o) 回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。
int lastIndexOf(Object o) 返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1。
ListIterator listIterator() 返回列表中的列表迭代器(按适当的顺序)。
ListIterator listIterator(int index) 从列表中的指定位置开始,返回列表中的元素(按正确顺序)的列表迭代器。
List subList(int fromIndex,int toIndex) 返回此列表中指定的fromIndex(含)和toIndex之间的视图
ListIterator
interface ListIterator<E> extends Iterator<E>
允许程序员沿任一方向遍历列表的列表的迭代器 List中Iterator的实现类
add(E e) 将指定的元素插入列表(可选操作)。
hasNext() 返回 true 如果遍历正向列表,列表迭代器有多个元素。
hasPrevious() 返回 true 如果遍历反向列表,列表迭代器有多个元素。
E next() 返回列表中的下一个元素,并且前进光标位置。
int nextIndex() 返回随后调用 next()返回的元素的索引.
int previousIndex() 返回由后续调用 previous()返回的元素的索引。
void remove() 从列表中删除由 next()或 previous()返回的最后一个元素(可选操作)。
void set(E e) 用 指定的元素替换由 next()或 previous()返回的最后一个元素(可选操作)。
ArrayList
class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
底层使用数组实现的存储类 特点:查询效率高 增删效率低 线程不安全 可以有null值
ArrayList() 构造方法里面初始化一个数组 用来储存数据
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
boolean add(E e) 如果数组长度足够则添加改元素到数组 不够就增加现有长度的一半 然后把原有的元素添加到新数组中
public boolean add(E e) {
ensureCapacityInternal(size + 1); // 判断数组集合的长度是否够
elementData[size++] = e; //
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { // 数组为空
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); //默认10个长度
}
ensureExplicitCapacity(minCapacity);
}
// 如果该数组是刚初始化的 minCapacity =10 如果不是 mincapacity = size+1
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// 如果数组长度不够放该长度 调用grow
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); //增加原始数组的一半
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
//把旧数组的元素拷贝到新长度的数组 然后返回
elementData = Arrays.copyOf(elementData, newCapacity);
}
E remove(int index) 把要删除的元素位置前边和后边 拷贝到一个新数组里面 然后把最后一个位置的元素 =null
public E remove(int index) {
modCount++;
E oldValue = (E) elementData[index];
int numMoved = size - index - 1;
// 把要删除的位置前面和后面拷贝到一个新数组
if (numMoved > 0)
//要拷贝的数组 要拷贝的开始位置 拷贝到的数组 要拷贝的位置 拷贝的个数
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null;
return oldValue;
}
ListIterator<E> listIterator()
获取该集合的迭代器
public ListIterator<E> listIterator() {
return new ListItr(0);
}
private class ListItr extends Itr implements ListIterator<E> {
....
}
Itr
class ListItr extends Itr implements ListIterator<E>
Array 的列表迭代器
cursor lastRet
int cursor; // 下一次要返回的位置
int lastRet = -1; // 当前返回位置
boolean hasNext() 如果游标小于数组数 返回ture
protected int limit = ArrayList.this.size;
public boolean hasNext() {
return cursor < limit;
}
E next() 返回当前游标的元素 然后游标+1 lastRet=当前返回元素的位置
public E next() {
int i = cursor; // i 等于当前游标
Object[] elementData = ArrayList.this.elementData;
cursor = i + 1; // 游标 +1
return (E) elementData[lastRet = i]; //lastRet = 返回位置 返回当前元素
}
void remove() 数组删除该游标的元素 游标(cursor)=上一次输出的位置 上一次位置(lastRet)等于-1 size()--
public void remove() {
try {
ArrayList.this.remove(lastRet); // 删除已经输出的位置的元素
cursor = lastRet; // 下一个输出位置 等于 前一个位置
lastRet = -1; // 已经输出的元素 删除 所以已经输出的没了 所以lastRet为-1
expectedModCount = modCount;
limit--;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
ListItr
ListItr extends Itr implements ListIterator<E>
构造方法 cursor 下一输出的位置 表示从什么位置开始
ListItr(int index) {
super();
cursor = index;
}
boolean hasPrevious() int nextIndex() int previousIndex()
public boolean hasPrevious() { // 是否有上一个元素
return cursor != 0;
}
public int nextIndex() { //下一个输出元素的位置
return cursor;
}
public int previousIndex() { //上一个输出元素的位置
return cursor - 1;
}
E previous() 输出上一个输出的元素
public E previous() {
int i = cursor - 1; // 游标-1
Object[] elementData = ArrayList.this.elementData;
cursor = i; //
return (E) elementData[lastRet = i];
}
LinkedList
class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
底层是用双向链表实现的储存 查询效率低 增删效率高 线程不安全 可以为null值
static class Node<E> 链表保存数据类
private static class Node<E> {
E item; // 数据
Node<E> next; // 下一个节点
Node<E> prev; //上一个节点
}
first last
//
// 链表第一个
transient Node<E> first;
// 链表最后一个
transient Node<E> last;
boolean add(E e) 把E放到Node对象中 假如last==null 说明链表没有数据 frist==新的Node 假如last!=null 最后一个Node链接新的 last=新Node
public boolean add(E e) {
linkLast(e);
return true;
}
void linkLast(E e) {
final Node<E> l = last;
// 新建一个Node 把链表最后一个node放到新的前面
final Node<E> newNode = new Node<>(l, e, null);
// last 等于 新建的node
last = newNode;
if (l == null) // 链表没有数据 把新Node当成第一个
first = newNode;
else
l.next = newNode; // last 等于 新的node
size++;
modCount++;
}
E remove(int index)
public E remove(int index) {
checkElementIndex(index); //检测index 是否规范
return unlink(node(index));
}
E unlink(Node<E> x) {
final E element = x.item; // 取出要删除位置的数据
final Node<E> next = x.next;
final Node<E> prev = x.prev;
if (prev == null) { // 该Node前面节点为空说明是 frist Node
first = next; // 让该节点下一个节点 = frist (间接删除)
} else { // 该Node 前一个节点的next = 该Node的后一个节点
prev.next = next;
x.prev = null;
}
if (next == null) { // 该Node后面的节点为空说明是last节点
last = prev;// 让该节点的上一个节点 = last(间接删除)
} else { //该Node 后一个节点的prev = 该Node的前一个节点
next.prev = prev;
x.next = null;
}
x.item = null;
size--;
modCount++;
return element;
}
Node<E> node(int index) 判断index 是否大于size/2 大于从链表后面开始遍历 小于从前面开始 最后返回该位置的node
Node<E> node(int index) { // 根据位置返回节点
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
E get(int index)
返回该位置节点的数据
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
E set(int index, E element) 设置Index位置上的值 返回修改掉的值
public E set(int index, E element) {
Node<E> x = node(index);
E oldVal = x.item;
x.item = element;
return oldVal;
}