add()方法
- 调用add()方法添加元素,会调用linkedlast(),把新添加的元素放在原链表最后一位
- 首先获取原链表最后一个元素,根据当前输入的元素构建一个node,把原最后一位元素最为新构建的元素中pre对应的变量
- 新构建的node覆盖之前最后一个node变量
- 判断为添加前的最后一位是否为空,如果为空,新添加的一个node也是first变量对应的元素
- 如果添加前的最后一位不为空,则未添加前的最后一位元素的next变量被新添加的元素覆盖
- 链表长度加1,链表修改统计加1
public boolean add(E e) {
// 调用 linkLast方法,把新添加的元素添加到链表的最后一个位置
linkLast(e);
return true;
}
// 把元素添加在链表的最后一个位置的方法
void linkLast(E e) {
// 获取链表中最后一个元素
final Node<E> l = last;
// 该方法是把元素放在最后一个位置,所以创建一个新的node,变量前一个元素是没添加前最后一个
final Node<E> newNode = new Node<>(l, e, null);
// 把新添加的元素作为最后一个
last = newNode;
// 判断新元素未添加前的最后一个是否是空,如果是,则新添加的元素即是最后一个,也是第一个
if (l == null)
// 新添加的元素赋给第一个
first = newNode;
else
// 如果不为空,则原来最有一个元素的next遍历绑定新添加的元素
l.next = newNode;
// 链表长度加1,修改次数加1
size++;
modCount++;
}
get()方法
- 首先,校验输入的下标是否满足linkedlist中的长度范围,如果不满足,抛出异常
- 如果满足,调用node()方法,首先把原长度除以2,判断当前输入的下标是在上半部分还是下半部分
- 如果在上半部分,从上往下遍历,如果在下半部分,从后往前遍历.
- 最后一个元素就是要找的元素
public E get(int index) {
// 检查索引是否规范
checkElementIndex(index);
// 获取指定下标的元素
return node(index).item;
}
// 判断索引是否规范
private void checkElementIndex(int index) {
if (!isElementIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
// 判断索引是否在链表长度的范围内
private boolean isElementIndex(int index) {
return index >= 0 && index < size;
}
Node<E> node(int index) {
// 把链表的长度向右移一个单位,也就是除以2, 判断录入的索引是在前半段还是后半段
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;
}
}