文章目录
前言
- LinkedList集合底层是使用双链表实现的,所以LinkedList集合没有像ArrayList集合那样的扩容机制(ArrayList集合底层是数组),它想要增加元素直接申请一个链表节点插入到链表中即可。
- LinkedList集合可以添加值为null的元素。
一、LinkedList的初始化
- LinkedList():无参构造,创建了一个空的链表。
- LinkedList(Collection<? extends E> c):有参构造,参数可以是List、Set接口的所有实现类。注意,Map接口的实现类不可以作为参数。
源码如下:
/**
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*
* @param c the collection whose elements are to be placed into this list
* @throws NullPointerException if the specified collection is null
*/
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
二、LinkedList增加元素
- public boolean add(E e):在双链表的尾部增添新的元素。
源码如下:
/**
* Appends the specified element to the end of this list.
*
* <p>This method is equivalent to {@link #addLast}.
*
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add})
*/
public boolean add(E e) {
linkLast(e);
return true;
}
根据源码,add()方法调用了linkLast(E e)方法,该方法源码如下:
/**
* Links e as last element.
*/
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++;
}
即创建值为e的新节点,如果双链表中没有元素,即是个空链表,那么将first头指针指向新节点。
如果双链表中有元素,last(最后一个元素).next指向新节点,完成尾部插入。
- add(int index, E element):在指定位置插入新元素。源码如下:
/**
* Inserts the specified element at the specified position in this list.
* Shifts the element currently at that position (if any) and any
* subsequent elements to the right (adds one to their indices).
*
* @param index index at which the specified element is to be inserted
* @param element element to be inserted
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
调用checkPositionIndex(index)方法判断传进来的index有没有越界,越界则抛出异常,源码如下:
private void checkPositionIndex(int index) {
if (!isPositionIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
checkPositionIndex(index)方法中有调用了isPositionIndex(index)方法,用来检索index是否在双链表长度区间内,源码如下:
/**
* Tells if the argument is the index of a valid position for an
* iterator or an add operation.
*/
private boolean isPositionIndex(int index) {
return index >= 0 && index <= size;
}
即index在长度区间内,返回true,否则返回false。
是否越界判断完之后执行add(int index, E element)方法后面的代码。
判断index是否等于双链表的长度,
相等的话,直接调用linkLast(element)方法,在链表尾部插入新元素。
如果不相等,则调用linkBefore(element, node(index))方法,在原链表index位置之前插入新元素即可。linkBefore源码如下:
/**
* Inserts element e before non-null Node succ.
*/
void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;
final Node<E> newNode = new