LinkedList源码学习
链表数据结构
当前节点会保存上一个、下一个节点。 参见 LinkedList的Node类
实现:
1. 内部链表的方式。
1.1 添加元素。追加的方式,创建一个新的节点[Node],用最后一个节点关联新的节点。
1.2 删除元素
1.2.1 通过对象删除。遍历链表,删除第一个匹配的对象
修改链表关联结构
2. 内部是同步[modCount]
2.1 LinkedList数据结构变化的时候,都会将modCount++。
2.2 采用Iterator遍历的元素, next()会去检查集合是否被修改[checkForComodification],如果集合变更会抛出异常
类似于数据库层面的 乐观锁 机制。 可以通过 Iterator的api去删除元素
3. 数组结构,内部存储数据是有序的,并且数据可以为null
源码实现
package xin.rtime.collections.list; import java.util.ConcurrentModificationException; import java.util.Iterator; import java.util.ListIterator; import java.util.NoSuchElementException; // 链表的源码实现 public class LinkedList<E> { transient int size = 0; // 当前链表的size transient Node<E> first; // 首节点 transient Node<E> last; // 尾节点 private int modCount = 0; // 结构修改次数 // 添加节点 public boolean add(E e) { linkLast(e); return true; } // 删除节点 public boolean remove(Object o) { if (o == null) { for (Node<E> x = first; x != null; x = x.next) { if (x.item == null) { unlink(x); return true; } } } else { for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) { // equals unlink(x); return true; } } } return false; } // 获取节点 public E get(int index) { checkElementIndex(index); // 检查元素Index是否存在 , 不存在会抛出数组越界 return node(index).item; } // 获取链表size public int size() { return size; } public Iterator<E> iterator() { return listIterator(); } public ListIterator<E> listIterator() { return listIterator(0); } Node<E> node(int index) { // assert isElementIndex(index); if (index < (size >> 1)) { // 当前index 小于 当前一半容量的 size Node<E> x = first; // 当前节点 等于 首节点 for (int i = 0; i < index; i++) // 遍历 index -1 次 x = x.next; // x 等于当前节点的下一个节点 return x; } else { // 大于 Node<E> x = last; for (int i = size - 1; i > index; i--) // 从尾部开始遍历 x = x.prev; // x 等于当前节点的上一个节点 return x; } } private void checkElementIndex(int index) { if (!isElementIndex(index)) // 节点index是否在链表的容量范围内 throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } private boolean isElementIndex(int index) { return index >= 0 && index < size; } private String outOfBoundsMsg(int index) { return "Index: "+index+", Size: "+size; } // 获得首个节点值 public E getFirst() { final Node<E> f = first; if (f == null) throw new NoSuchElementException(); return f.item; } // 获得尾部节点值 public E getLast() { final Node<E> l = last; if (l == null) throw new NoSuchElementException(); return l.item; } // 获得所有节点值 public Object[] toArray() { Object[] result = new Object[size]; int i = 0; for (Node<E> x = first; x != null; x = x.next) result[i++] = x.item; return result; } public ListIterator<E> listIterator(int index) { checkPositionIndex(index); return new ListItr(index); } private void checkPositionIndex(int index) { if (!isPositionIndex(index)) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } // 判断当前节点index是否存在 private boolean isPositionIndex(int index) { return index >= 0 && index <= size; } private class ListItr implements ListIterator<E> { private Node<E> lastReturned = null; // 返回的节点 private Node<E> next; // 下个节点 private int nextIndex; // 下个节点 下标 private int expectedModCount = modCount; // 预期的修改次数 = 等于遍历时的修改次数 ListItr(int index) { // assert isPositionIndex(index); next = (index == size) ? null : node(index); nextIndex = index; } public boolean hasNext() { return nextIndex < size; } public E next() { checkForComodification(); // 校验当前链表是否被改动 if (!hasNext()) throw new NoSuchElementException(); lastReturned = next; next = next.next; nextIndex++; return lastReturned.item; } public boolean hasPrevious() { return nextIndex > 0; } public E previous() { checkForComodification(); // 校验当前链表是否被改动 if (!hasPrevious()) throw new NoSuchElementException(); lastReturned = next = (next == null) ? last : next.prev; nextIndex--; return lastReturned.item; } public int nextIndex() { return nextIndex; } public int previousIndex() { return nextIndex - 1; } public void remove() { checkForComodification(); // 校验当前链表是否被改动 if (lastReturned == null) throw new IllegalStateException(); Node<E> lastNext = lastReturned.next; unlink(lastReturned); // 剔除节点 if (next == lastReturned) next = lastNext; else nextIndex--; lastReturned = null; expectedModCount++; } // 当前节点设置值 public void set(E e) { if (lastReturned == null) throw new IllegalStateException(); checkForComodification(); lastReturned.item = e; } public void add(E e) { checkForComodification(); lastReturned = null; if (next == null) // 下一个节点为null linkLast(e); // 在尾部插入 else linkBefore(e, next); // 在指定节点之前插入 nextIndex++; expectedModCount++; } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } } private 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) { // 上一个节点为空 first = next; // 首节点 = 当前节点下一个节点 } else { // 不为空 prev.next = next; // 上一个节点的下一个节点 等于 当前节点的 下一个节点 x.prev = null; // 当前节点的上一个节点置为null gc回收 } if (next == null) { // 下一个节点为空 last = prev; // 最后节点 = 当前节点的上一个节点 } else { // 不为空 next.prev = prev; // 上一个节点的上一个节点 等于 当前节点的上一个节点 x.next = null; // 当前节点的下一个节点置为null gc回收 } x.item = null; // 当前元素置为null gc回收 size--; // 长度 + 1 modCount++; // 修改次数+1 return element; } // 在链表的尾部插入节点 void linkLast(E e) { final Node<E> l = last; // 最后一个元素 final Node<E> newNode = new Node<>(l, e, null); // 上一个元素,当前元素,null last = newNode; // 最后一个节点等新建的节点 if (l == null) // 如果最后一个节点为空 first = newNode; // 出现一个情况: 当链表为空的时候 , first 和 last 都为 newNode else l.next = newNode; //最后节点的下一个节点,等于当前节点 size++; // 链表长度+1 modCount++; // 修改次数+1 } // 在指定节点添加上一个节点 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++; } // 链表节点 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; } } }
posted on 2018-11-28 20:59 Luis、Yang、 阅读(134) 评论(0) 编辑 收藏 举报