LinkedList就是一个双向链表结构,存储地址是不连续的,底层通过一个个内部类Node的实例串联起来存储数据,没有容量限制,增删节点不需要移动数据,速度快,但是随机访问速度慢,需要从头到尾或者从尾到头遍历,适合增删频繁,随机访问较少的业务场景。非同步,线程不安全;支持null元素、有顺序、元素可以重复;可以作为栈、队列、双端队列数据结构使用。
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
存储结构
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查找元素每次都是从头部开始吗?
不是的,LinkedList的查找底层是通过node(int index)方法实现的,这个方法会先判读index是否大于链表的长度的一半,如果大于就从尾部开始遍历,如果不大于,就从头部开始遍历
有什么办法提升链表随机查找速度吗?
可以通过跳表方式增强随机查找能力,即维护一个节点索引数组,数组中保存节点的地址引用,数组下标和节点的某个数据要一致,这样直接通过数组下标找到节点的引用,如果在数组找不到精确匹配的索引,可以找一个就近的索引,得到节点,往后遍历节点即可,这样也能大大提升速度
LinkedList<String> list=new LinkedList<>();
// 增
Boolean offerFirst(E e); // 【Deque接口】 将对象e插入到双端队列头部
// 同作用:【Deque接口】 void addFirst(E e); 容间不足时,抛出IllegalStateException异常; 不推荐
// 同作用:【Deque接口】 void push(E e);
Boolean offerLast(E e); // 【Deque接口】 将对象e插入到双端队列尾部;
// 同作用:【Deque接口】 void addLast(E e); 容间不足时,抛出IllegalStateException异常; 不推荐
Boolean offer(E e);// 【Queue接口】 将对象e插入队列尾部,成功返回true,失败(没有空间)返回false
// 同作用:【Queue接口】 Boolean add(obj); 若失败(没有空间)抛出异常IllegalStateException; 不推荐
list.add(index, obj); // void 在指定位置插入指定元素.
list.addAll(tmp_list); // boolean 插入指定列表到列表尾部.
list.addAll(index,tmp_list);// boolean 在指定位置插入指定列表.
// 删
E pollFirst(); // 【Deque接口】 获取并移除队列第一个元素,队列为空,返回null;
// 同作用:【Deque接口】 E removeFirst();队列为空,抛出NoSuchElementException异常; 不推荐
E pollLast(); // 【Deque接口】 获取并移除队列最后一个元素,队列为空,返回null;
// 同作用:【Deque接口】 E removeLast();队列为空,抛出NoSuchElementException异常; 不推荐
// 同作用:【Deque接口】 E pop();
E poll(); // 【Queue接口】 获取并移除队列头部元素,如果队列为空,返回null;
// 同作用:【Queue接口】 E remove(); 如果队列为空,抛出NoSuchElementException异常; 不推荐
Boolean removeFirstOccurrence(Object o); // 【Deque接口】 移除第一个满足 (o==null ? e==null : o.equals(e)) 的元素
Boolean removeLastOccurrence(Object o);// 【Deque接口】 移除最后一个满足 (o==null ? e==null : o.equals(e)) 的元素
list.remove(obj); // boolean 删除指定元素
list.remove(index); // object 根据索引删除元素
list.removeAll(tmp_list); // boolean 批量删除元素
list.removeIf(e -> 条件); // boolean 删除满足指定条件的元素 (e表示列表中的每个元素)
list.retainAll(tmp_list); // boolean 将存在于list但不存在于tmp_list的元素从list中删除
list.clear(); // void 清空列表
// 改
list.set(index, new_obj); // object 修改指定位置的元素
list.replaceAll(e -> 修改动作 ); // void 修改所有元素
list.sort(Comparator.naturalOrder()); // void 排序。可以用Comparator,也可以用Comparable
list.toString(); // string 转化为字符串
// 查
E peekFirst(); // 【Deque接口】 获取队列第一个元素,队列为空,返回null;
// 同作用: 【Deque接口】 E getFirst(); 队列为空,抛出NoSuchElementException异常; 不推荐
E peekLast(); // 【Deque接口】 获取队列最后一个元素,队列为空,返回null;
// 同作用: 【Deque接口】 E getLast(); 队列为空,抛出NoSuchElementException异常; 不推荐
E peek(); // 【Queue接口】 获取但不移除队列头部元素,如果队列为空,返回null;
// 同作用:// 【Queue接口】 E element(); 如果队列为空,抛出NoSuchElementException异常;不推荐
Iterator<E> descendingIterator(); // 【Deque接口】 双端队列尾部到头部的一个迭代器;
list.get(index); // object 返回指定位置的元素
list.indexOf(obj); // int 返回指定元素的下标
list.lastIndexOf(obj); // int 返回指定元素最后一次出现的下标
list.contains(obj); // boolean 查看list中是否存在某个元素
list.containsAll(tmp_list); // boolean 检测list中是否包含指定集合中的所有元素。
list.isEmpty(); // boolean 判空
list.size(); // int 当前列表中元素的个数