LinkedList
底层是双向链表,可当作堆栈、队列或双端队列,元素可以为null,理论上对元素个数没有限制。线程不安全,如果多个线程同时访问一个链接列表,并至少线程进行结构性修改,它必须保持外部同步。(结构上的修改是指添加或删除一个或多个元素的操作;仅设置元素的值不是结构修改。)List list = Collections.synchronizedList(new LinkedList(...));
常用方法
LinkedList<String> linkedList = new LinkedList<>(); linkedList.add("a"); // 添加到链表尾部 linkedList.addLast("last"); // 添加到链表尾部(等同于add) linkedList.offer("last_last"); // 添加到链表尾部 linkedList.offerLast("last_last_last"); // 添加到链表尾部 linkedList.add(1,"b"); // 指定索引添加元素,其他元素后移 ArrayList<String> arrayList = new ArrayList<>(); arrayList.add("arr_list1"); arrayList.add("arr_list2"); linkedList.addAll(arrayList); // 将指定Collection实现类的对象中的元素依次添加到尾部 linkedList.addAll(1,arrayList); // 将指定Collection实现类的对象中的元素依次添加到指定索引 linkedList.size(); // 返回元素个数 linkedList.addFirst("first"); // 添加到链表头部 linkedList.offerFirst("first_first"); // 添加到链表头部 linkedList.set(0,"aaa"); // 设置指定索引的元素 linkedList.get(1); // 获取指定索引的元素 linkedList.contains("a"); // 判断是否包含指定元素 linkedList.indexOf("a"); // 获取指定元素的第一个索引 linkedList.lastIndexOf("a"); // 获取指定元素的最后一个索引 linkedList.element(); // 获取链表头元素(但不移除) linkedList.getFirst(); // 获取第一个元素(但不移除) linkedList.peek(); // 获取第一个元素(但不移除) linkedList.peekFirst(); // 获取第一个元素(但不移除) linkedList.poll(); // 获取第一个元素(并移除) linkedList.pollFirst(); // 获取第一个元素(并移除) linkedList.remove(); // 移除并返回第一个元素 linkedList.removeFirst(); // 移除并返回第一个元素 linkedList.pop(); // 移除第一个元素 linkedList.peekLast(); // 获取最后一个元素(但不移除) linkedList.pollLast(); // 获取最后一个元素(并移除) linkedList.getLast(); // 获取链表最后一个元素(但不移除) linkedList.removeLast(); // 移除并返回最后一个元素 linkedList.push("aaaaa"); // 添加到头部 linkedList.remove("aaaaa"); // 移除指定元素 linkedList.removeLastOccurrence("last"); // 移除最后一次出现的指定元素 linkedList.removeFirstOccurrence("b"); // 移除第一次出现的指定元素 Object[] arr; arr = linkedList.toArray(); // 转化为数组 linkedList.toArray(arr); // 转化为数组 ListIterator listIterator = linkedList.listIterator(); // 返回迭代器 while (listIterator.hasNext()) { System.out.println(listIterator.next()); } Iterator listIterator1 = linkedList.descendingIterator(); // 返回倒序迭代器 while (listIterator1.hasNext()) { System.out.println(listIterator1.next()); }
源码阅读
继承了AbstractSequentialList<E>,实现了implements List<E>, Deque<E>, Cloneable, java.io.Serializable接口。
字段
transient int size = 0; // 链表结点数 transient Node<E> first; // 指向头结点 transient Node<E> last; // 指向尾结点
构造器
// 构造一个空链表 public LinkedList() { } // 用指定的Collection实现类对象中元素构造 public LinkedList(Collection<? extends E> c) { this(); addAll(c); }
内部类Node类
private static class Node<E> { E item; Node<E> next; Node<E> prev; // 构建新结点需指定prev域和next域 Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } }
方法
// 将e链接为第一个元素 private void linkFirst(E e) { final Node<E> f = first; // 作为第一个元素,其prev域需是null final Node<E> newNode = new Node<>(null, e, f); first = newNode; if (f == null) last = newNode; else f.prev = newNode; size++; modCount++; } // 将e链接为最后一个元素 void linkLast(E e) { final Node<E> l = last; // 作为第一个元素,其next域需是null final Node<E> newNode = new Node<>(l, e, null); last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; modCount++; }
// 将结点e插入到succ结点之前 void linkBefore(E e, Node<E> succ) { final Node<E> pred = succ.prev; // 新结点的prev域和next域分别是pred和succ final Node<E> newNode = new Node<>(pred, e, succ); succ.prev = newNode; // 使succ的向前指针指向新结点 if (pred == null) // 之前的链表只有一个结点 first = newNode; else pred.next = newNode; // succ原来的前一个结点指向新结点 size++; modCount++; }
本方法图示:
// 将f不再链接为第一个元素 private E unlinkFirst(Node<E> f) { final E element = f.item; final Node<E> next = f.next; f.item = null; f.next = null; first = next; if (next == null) last = null; else next.prev = null; size--; modCount++; return element; } // 将l不再链接为最后一个元素 private E unlinkLast(Node<E> l) { final E element = l.item; final Node<E> prev = l.prev; l.item = null; l.prev = null; // help GC last = prev; if (prev == null) first = null; else prev.next = null; size--; modCount++; return element; } // 将结点x解除链接 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; } if (next == null) { last = prev; } else { next.prev = prev; x.next = null; } x.item = null; size--; modCount++; return element; } // 移除头结点 public E removeFirst() { final Node<E> f = first; if (f == null) throw new NoSuchElementException(); return unlinkFirst(f); } // 移除尾结点 public E removeLast() { final Node<E> l = last; if (l == null) throw new NoSuchElementException(); return unlinkLast(l); } // 移除指定对象 public boolean remove(Object o) { if (o == null) { // null元素单独处理 for (Node<E> x = first; x != null; x = x.next) { if (x.item == null) { // 用“==” unlink(x); return true; } } } else { // 非null元素 for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) { // 用“equals” unlink(x); return true; } } } return false; } public void clear() { for (Node<E> x = first; x != null; ) { Node<E> next = x.next; // 保存后一个结点 x.item = null; // 本结点全部置null x.next = null; x.prev = null; x = next; // 移到下一个结点 } first = last = null; size = 0; 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) { 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; } } // 获取指定索引的元素 public E get(int index) { checkElementIndex(index); return node(index).item; }
原文:https://www.cnblogs.com/jiazhongxin/p/12860055.html