当前位置: 首页 > 编程笔记 >

详解Java 集合系列(三)—— LinkedList

子车宏浚
2023-03-14
本文向大家介绍详解Java 集合系列(三)—— LinkedList,包括了详解Java 集合系列(三)—— LinkedList的使用技巧和注意事项,需要的朋友参考一下

LinkedList

LinkedList是一种可以在任何位置进行高效地插入和删除操作的有序序列。
它的最基本存储结构是一个节点:每个节点将存储对象,以及前后节点的引用。

结构图

从上面的结构图中,我们可以了解到 ListedList 底层是基于双向链表实现的。
围起来的可以看成 LinkedList 类,它定义了三个 transient 成员变量:first、last、size。这三个变量是整个 LinkedList 类的关键点。

  1. 由于是双向链表(每个node都有保存前后节点的引用),因此我们不管是由 first 还是 last 节点开始迭代,都可以将整个链表的数据找出来;
  2. 在查询、随机插入以及set等操作都有涉及 size 判断;
  3. 由于 LinkedList 是双向链表,类中只存储了首尾两个节点,因此查询第n个元素都要从头遍历进行查找。

 源码分析

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;
 }
 
 /**
  * Links e as last element.
  */
 void linkLast(E e) {
  final Node<E> l = last;        // 将当前最后一个元素寄存在 l
  final Node<E> newNode = new Node<>(l, e, null);  // new 一个新节点:pre的引用为l;存储元素为e;next的引用为null
  last = newNode;          // 将新节点引用覆盖成员变量 last
  if (l == null)          
   first = newNode;        // 若l为null,说明之前链表为空,此时新节点为首个元素
  else
   l.next = newNode;        // 否则,更新l的next引用
  size++;            // size+1
  modCount++;           // 非查询操作 modCount 都会 +1
 }

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); // 检查 index 是否大于 size

  if (index == size)
   linkLast(element);  // 直接在链表末尾追加
  else
   linkBefore(element, node(index)); // 插入index 节点前面
 }
 
 
 // 检查 index 是否超出范围 超出则抛出 IndexOutOfBoundsException
 private void checkPositionIndex(int index) {
  if (!isPositionIndex(index))
   throw new IndexOutOfBoundsException(outOfBoundsMsg(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 查找 node
  * 该方法利用了双向链表的特性,index 距离哪个链表头近就从哪边开始开始遍历
  * 时间复杂度为 O(n/2);
  * 当 index 接近 size 的中间值时,效率最低
  * Returns the (non-null) Node at the specified element index.
  */
 Node<E> node(int index) {
  // assert isElementIndex(index);

  if (index < (size >> 1)) {   // size 右移一位(除以2)
   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;
  }
 }

优缺点

优点

增删元素效率高(只需要更新节点附近的引用即可)

缺点

由于查询需要进行遍历,因此效率低

知识脑图

以上所述是小编给大家介绍的Java 集合系列(三)—— LinkedList详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对小牛知识库网站的支持!

 类似资料:
  • 本文向大家介绍java集合中的list详解,包括了java集合中的list详解的使用技巧和注意事项,需要的朋友参考一下 1、List接口 该接口定义的元素是有序的且可重复的。相当于数学里面的数列,有序可重复 booleanaddAll(intindex,Collection<?extendsE>c);将指定集合中所有元素,插入至本集合第index个元素之后defaultvoidreplaceAll

  • 这篇文章总结了所有的Java集合(Collection)。主要介绍各个集合的特性和用途,以及在不同的集合类型之间转换的方式。 1. Arrays Array是Java特有的数组。在你知道所要处理数据元素个数的情况下非常好用。java.util.Arrays 包含了许多处理数据的实用方法: 方法声明 功能描述 Arrays.asList() 可以从 Array 转换成 List。可以作为其他集合类型

  • 本文向大家介绍js模仿java的Map集合详解,包括了js模仿java的Map集合详解的使用技巧和注意事项,需要的朋友参考一下 java.util 中的集合类包含 Java 中某些最常用的类。最常用的集合类是 List 和 Map。List 的具体实现包括 ArrayList 和 Vector,它们是可变大小的列表,比较适合构建、存储和操作任何类型对象元素列表。List 适用于按数值索引访问元素的

  • 本文向大家介绍Java总结篇系列:Java泛型详解,包括了Java总结篇系列:Java泛型详解的使用技巧和注意事项,需要的朋友参考一下 一. 泛型概念的提出(为什么需要泛型)? 首先,我们看下下面这段简短的代码: 定义了一个List类型的集合,先向其中加入了两个字符串类型的值,随后加入一个Integer类型的值。这是完全允许的,因为此时list默认的类型为Object类型。在之后的循环中,由于忘记

  • 本文向大家介绍Backbone.js中的集合详解,包括了Backbone.js中的集合详解的使用技巧和注意事项,需要的朋友参考一下 Backbone.js的集合只是一个简单的有序集的模型。通过适应模型和集合,我们可以避免数据处理逻辑放到了我们的视图层。此外,模型和集合还提供了便利的与后端一起工作的方法,当数据发生变化时,可以自动化地标记Backbone.js视图。这样,它可以用于如下的情况: 通常

  • 本文向大家介绍基于java中集合的概念(详解),包括了基于java中集合的概念(详解)的使用技巧和注意事项,需要的朋友参考一下 1.集合是储存对象的,长度可变,可以封装不同的对象 2.迭代器: 其实就是取出元素的方式(只能判断,取出,移除,无法增加) 就是把取出方式定义在集合内部,这样取出方式就可以直接访问集合内部的元素,那么取出方式就被定义成了内部类. 二每一个容器的数据结构不同,所以取出的动作