Java_LinkedList底层结构

LinkedList的说明:

1)LinkedList实现了双向链表和双端队列特点

2)可以添加任意元素(元素可以重复),包括null

3)线程不安全,没有实现同步

LinkedList底层操作机制:

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

2)LinkedList中维护了两个属性first和last分别指向 首节点和尾节点

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

4)所以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高

底层源码分析(以增删改查为例):

java 复制代码
package com.ArrListStu.LinkedList_;

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

@SuppressWarnings({"all"})
public class LinkedListCRUD {
    public static void main(String[] args) {

        LinkedList linkedList = new LinkedList();
        /*
        第一步 new LinkedList
        public LinkedList() {} 空参构造器
        这时,linkedList 的属性first = null,last = null

        第二步 执行add方法
        public boolean add(E e) {
            linkLast(e);
            return true;
        }
        linkLast(e); 也就是将first和last同时指向它

        第三步 进入linkLast()
        void linkLast(E e) {
            final Node<E> l = last;     //此时last = null
            final Node<E> newNode = new Node<>(l, e, null);
            last = newNode;
            if (l == null)
                first = newNode;
            else
                l.next = newNode;
            size++;
            modCount++;
        }
        将新的节点,加入到双向链表的最后
         */
        linkedList.add(1);
        linkedList.add(2);
        linkedList.add(3);
        System.out.println("linkedList=" + linkedList);

        linkedList.remove();
         /*
         linkedList.remove(); // 这里默认删除的是第一个结点
          1. 执行 removeFirst
            public E remove() {
                return removeFirst();
            }
         2. 执行
            public E removeFirst() {
                final Node<E> f = first;
                if (f == null)
                    throw new NoSuchElementException();
                return unlinkFirst(f);
            }
          3. 执行 unlinkFirst, 将 f 指向的双向链表的第一个结点拿掉
            private E unlinkFirst(Node<E> f) {
                // assert f == first && f != null;
                final E element = f.item;
                final Node<E> next = f.next;
                f.item = null;
                f.next = null; // help GC
                first = next;
                if (next == null)
                    last = null;
                else
                    next.prev = null;
                size--;
                modCount++;
                return element;
            }
         */
        System.out.println("linkedList=" + linkedList);

        linkedList.set(1, 999);
        System.out.println("linkedList=" + linkedList);


        Object o = linkedList.get(1);
        System.out.println(o);//999

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

        }

        System.out.println("===LinkeList遍历增强for====");
        for (Object o1 : linkedList) {
            System.out.println("o1=" + o1);
        }
        System.out.println("===LinkeList遍历普通for====");
        for (int i = 0; i < linkedList.size(); i++) {
            System.out.println(linkedList.get(i));
        }
    }
}

ArrayList和LinkedList比较:

如何选择ArrayList和LinkedList:

1)如果改查的操作多,选择ArrayList

2)如果增删的操作多,选择LinkedList

3)一般来说,在程序中,80%-90%都是查询,因此大部分情况下会选择ArrayList

4)在一个项目中,根据业务灵活选择,也可能一个模块使用的是ArrayList,另一个模块使用了LinkedList.也就是说,要根据业务来进行选择

相关推荐
枫叶丹4几秒前
【Qt开发】Qt系统(十一)-> Qt 音频
c语言·开发语言·c++·qt·音视频
长安城没有风3 分钟前
Java 高并发核心编程 ----- 线程池原理与实践(上)
java·juc
Remember_9933 分钟前
Spring 核心原理深度解析:Bean 作用域、生命周期与 Spring Boot 自动配置
java·前端·spring boot·后端·spring·面试
tlwlmy4 分钟前
python excel图片批量导出
开发语言·python·excel
散峰而望6 分钟前
【基础算法】穷举的艺术:在可能性森林中寻找答案
开发语言·数据结构·c++·算法·随机森林·github·动态规划
Java后端的Ai之路9 分钟前
【Python教程10】-开箱即用
android·开发语言·python
风流倜傥唐伯虎9 分钟前
java多线程打印
java·多线程
散峰而望9 分钟前
【基础算法】算法的“预谋”:前缀和如何改变游戏规则
开发语言·数据结构·c++·算法·github·动态规划·推荐算法
80530单词突击赢12 分钟前
云原生时代:.NET与Java的K8s进化论
java
深蓝电商API14 分钟前
异步爬虫中代理池的并发管理
开发语言·爬虫·python