LinkedList底层是通过链表实现的:
transient int size = 0;//容器元素数量
transient Node<E> first;//头结点
transient Node<E> last;//尾节点
private static class Node<E> {
E item;//节点内容
Node<E> next;//下一个节点
Node<E> prev;//前一个节点
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
LinkedList的构造函数:
有两种,第一种无参构造函数,第二种通过集合来创建列表。
public LinkedList() {
}
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
添加元素
public boolean add(E e) {
linkLast(e);
return true;
}
//在链表尾部添加新节点。
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
也可以在指定位置插入新元素
public void add(int index, E element) {
checkPositionIndex(index);//检查索引位置是否超过容器元素数量
if (index == size)
linkLast(element);//如果位置正好是尾部,就在链表尾部插入新节点
else
linkBefore(element, node(index));//否则在指定位置插入。
}
找到索引位置的节点
Node<E> node(int index) {
// assert isElementIndex(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;
}
}
在当前结点前面插入新的元素
void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}
节点删除
public E remove() {
return removeFirst();
}
public E removeFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);//删除头结点,头结点往后移
}
由于LinkedList实现了Queue接口,所以实现了poll,peek,offer,element方法
public E poll() {
final Node<E> f = first;
return (f == null) ? null : unlinkFirst(f);
}
删除头节点,并返回删除节点的值。
public E peek() {
final Node<E> f = first;
return (f == null) ? null : f.item;
}
获取头结点,但不删除,返回节点的值
public E element() {
return getFirst();
}
element()方法和peek()一样的效果。
public boolean offer(E e) {
return add(e);
}
offer()方式是使用add()方式实现的。
元素的遍历:
public static void main(String[] args) {
LinkedList<Integer> t=new LinkedList<Integer>();
t.add(1);
t.add(2);
t.add(3);
//正序遍历
for(int i:t){
System.out.println(i);
}
//从头遍历
Iterator<Integer> it=t.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//从指定索引位置开始遍历
Iterator<Integer> it2=t.listIterator(1);
while(it2.hasNext()){
System.out.println(it2.next());
}
}
总结:LinkedList是使用链表实现的,所以在指定位置删除和增加元素效率比ArrayList高,同时实现了Queue接口,从头节点删除,尾节点插入。LinkedList支持从指定位置遍历元素。