集合——LinkedList【底层代码】

基本介绍

  1. LinkedList 底层实现了 双向链表双端队列 特点
  2. 可以添加任意元素(元素可以重复),包括 null
  3. 线程不安全,没有实现同步

底层操作机制

  1. LinkedList 底层维护了一个双向链表.

  2. LinkedList 中维护了两个属性 firstlast 分别指向首节点和尾节点
    在这里插入图片描述

  3. 每个节点(Node对象),里面又维护了 prev、next、item 三个属性,其中通过 prev指向前一个,通过 next指向后一个节点。最终实现双向链表

  4. LinkedList 的元素的添加和删除,不是通过数组完成的,相对来说效率较高。
    在这里插入图片描述

  5. 模拟一个简单的双向链表


package collection_;

/**
 * @Author: Gin
 * @Description: 模拟一个简单的双向链表
 * @Modified By: Gin
 * @Date: Created in 17:18 2021/9/16
 */
public class List {
    public static void main(String[] args) {

        Node gin = new Node("Gin");
        Node sherry = new Node("Sherry");
        Node vermouth = new Node("Vermouth");

        // 连接三个结点,形成双向链表
        gin.next = sherry;
        sherry.next = vermouth;

        vermouth.pre = sherry;
        sherry.pre = gin;

        // 让 first 结点指向 Gin
        // 让 last 结点指向 Vermouth
        Node first = gin;
        Node last = vermouth;

        // 演示:从头到尾遍历
        System.out.println("==从头到尾遍历==");
        while(true){
            if(first == null){
                break;
            }
            System.out.println(first);
            first = first.next;
        }

        // 演示:从尾到头遍历
        System.out.println("==从尾到头遍历==");
        while(true){
            if(last == null){
                break;
            }
            System.out.println(last);
            last = last.pre;
        }

        // 再 Sherry 和 Vermouth 之间插入 Conan
        Node conan = new Node("Conan");
        sherry.next = conan;
        conan.next = vermouth;
        conan.pre = sherry;
        vermouth.pre = conan;

        // 遍历
        System.out.println("==插入新数据后==");
        first = gin;
        while(true){
            if(first == null){
                break;
            }
            System.out.println(first);
            first = first.next;
        }


    }
}
// 定义一个 Node 类,表示双向链表的一个结点
class Node{
    public Object item; // 真正存放数据
    public Node next; // 指向下一个结点
    public Node pre; // 指向上一个结点

    public Node(Object name) {
        this.item = name;
    }

    public String toString(){
        return "Node name = " + item;
    }
}


LinkedList 底层代码



package collection_;

import java.util.Iterator;
import java.util.LinkedList;

/**
 * @Author: Gin
 * @Description: 演示:LinkedList
 * @Modified By: Gin
 * @Date: Created in 20:51 2021/9/16
 */
public class LinkedListDetails {
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
        // new LinkedList() 方法底层:就是创建一个空的列表,且 first、last 都为 null
        /*
            public LinkedList() {
            }
         */


        linkedList.add(1);

        /*
            // add() 方法:
            public boolean add(E e) {
                linkLast(e);
                return true;
            }

            // linkLast() 方法:
            void linkLast(E e) {
                final Node<E> l = last;   // last 的指向赋给 l.【原链表如果没有数据,则 l 指向为 null,如果有数据,则 l 指向为最后一个元素】
                final Node<E> newNode = new Node<>(l, e, null); // 创建新结点 newNode 内容为 e,将 l 的指向赋给 e 的 prev
                last = newNode;           // 将新结点 newNode 赋给 last 的指向,此时新结点 newNode 为双向链表的最后一个元素
                if (l == null)            // 判断 l 的指向是否为 null,
                    first = newNode;      // l 的指向为 null 则将新结点 newNode 赋给 first 的指向
                else
                    l.next = newNode;     // l 的指向不为 null 则将 l.next 指向赋给新结点 newNode
                size++;                   // 链表大小 + 1
                modCount++;               // 对链表的操作次数 + 1
            }

            // linkLast() 方法中的 final Node<E> newNode = new Node<>(l, e, null) 底层:
            private static class Node<E> {
                E item;
                Node<E> next;
                Node<E> prev;

                Node(Node<E> prev, E element, Node<E> next) { // 三个参数分别为 prev、element、next
                    this.item = element;
                    this.next = next;
                    this.prev = prev;
                }
            }

         */

        linkedList.add(2);
        linkedList.add(3);

        System.out.println(linkedList);


        // 删除方法
        linkedList.remove(); // 默认删除第一个元素

        /*
            // .remove() 方法的底层:
            public E remove() {
                return removeFirst();
            }

            // removeFirst() 方法:
            public E removeFirst() {
                final Node<E> f = first;                 // 判断链表是否为空,为空则抛异常
                if (f == null)
                    throw new NoSuchElementException();
                return unlinkFirst(f);                   // 执行删除方法
            }

            // unlinkFirst() 方法:
            private E unlinkFirst(Node<E> f) {     // f 为第一个结点
                // assert f == first && f != null;
                final E element = f.item;          // 将 f 结点的内容赋给 element 用于返回
                final Node<E> next = f.next;       // 将 f.next 的指向赋给 next 结点
                f.item = null;                     // 将 f 结点的内容设置为 null
                f.next = null; // help GC          // 将 f.next 的指向设置为 null,并请求 GC 回收
                first = next;                      // 将 first 指向 next 结点
                if (next == null)                  // 如果 next 结点为空,则表示链表只有一个结点,且已经被删除,此时链表为 null
                    last = null;                   // 将 last 指向 null
                else                               // 如果 next 结点不为 null:
                    next.prev = null;              // 则将 next 结点的 prev 设置为 null,即 next 结点为第一个结点
                size--;                            // 链表的大小 - 1
                modCount++;                        // 对链表的修改次数 + 1
                return element;                    // 返回删除的元素
            }
         */

        System.out.println(linkedList);

        // 修改
        linkedList.set(1, 356);
        System.out.println(linkedList);

        // 迭代器遍历
        System.out.println("迭代器遍历==========");
        Iterator iterator = linkedList.iterator();
        while (iterator.hasNext()) {
            Object next = iterator.next();
            System.out.println(next);
        }

        // 增强for
        System.out.println("增强 for ===========");
        for (Object o : linkedList) {
            System.out.println(o);
        }

        // 普通 for
        System.out.println("普通 for ============");
        for (int i = 0; i < linkedList.size(); i++) {
            System.out.println(linkedList.get(i));
        }
    }
}



add() 方法底层代码图示

在这里插入图片描述

remove() 底层代码图示

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值