LinkedList双链表和源码解析

LinkedList双链表

  • LinkedList的全面说明

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

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

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

  • LinkedList的底层操作机制

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

    • LinkedList中维护了两个属性frist和last分别指向 首节点和尾节点

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

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

    • 模拟一个简单的双向链表

public class LinkedList01 {
    public static void main(String[] args) {
        //模拟简单构造器
        Node jack = new Node("Jack");
        Node tom = new Node("Tom");
        Node cici = new Node("CiCi");
​
        //连接三个节点,形成双向链表
        //jack -> tom -> cici
        jack.next = tom;
        tom.next = cici;
​
        //cici -> tom -> jack
        cici.pre = tom;
        tom.pre = jack;
​
        Node first = jack;   //让frist引用指向jack,就是双向链表的头节点
        Node last = cici;   //让last引用指向cici,就是双向链表的尾节点
​
        //从头到尾遍历
        while (true) {
            if(first == null){
                break;
            }
            //输出first信息
            System.out.println(first);
            first = first.next; //指向下一个
        }
        System.out.println("=============从头到尾遍历================");
​
        //从尾到头遍历
        while (true) {
            if(last == null){
                break;
            }
            //输出last信息
            System.out.println(last);
            last = last.pre;  //指向上一个
        }
        System.out.println("=============从尾到头遍历================");
​
        //添加数据
        Node xixi = new Node("XiXi");
        xixi.next = cici;
        xixi.pre = tom;
        tom.next = xixi;
        cici.pre = xixi;
        first = jack;  //first需要重新指向
        //从头到尾遍历
        while (true) {
            if(first == null){
                break;
            }
            //输出first信息
            System.out.println(first);
            first = first.next; //指向下一个
        }
        System.out.println("=============从头到尾遍历================");
        last = cici;  //last需要重新指向
        //从尾到头遍历
        while (true) {
            if(last == null){
                break;
            }
            //输出last信息
            System.out.println(last);
            last = last.pre;  //指向上一个
        }
        System.out.println("=============从尾到头遍历================");
    }
}
​
//定义一个Node 类,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;
    }
}
​
/*
1.LinkedList元素添加删除不是通过数组完成的,效率高
​
运行结果:
Node name = Jack
Node name = Tom
Node name = CiCi
=============从头到尾遍历================
Node name = CiCi
Node name = Tom
Node name = Jack
=============从尾到头遍历================
Node name = Jack
Node name = Tom
Node name = XiXi
Node name = CiCi
=============从头到尾遍历================
Node name = CiCi
Node name = XiXi
Node name = Tom
Node name = Jack
=============从尾到头遍历================
 */

LinkedList源码分析

import java.util.LinkedList;
​
public class LinkedListSource {
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
​
        //增加
        linkedList.add(1);
        linkedList.add(2);
        linkedList.add(3);
        System.out.println(linkedList);
        //删除
        linkedList.remove(1);
        System.out.println(linkedList);
        //修改
        linkedList.set(0,8);
        System.out.println(linkedList);
        //查询
        System.out.println(linkedList.get(1));
    }
}
​
/*
linkedList.add()源码解读:
1.
public LinkedList() {
}
2.这时的linkedList的属性 first = null last = null
3.
public boolean add(E e) {
    linkLast(e);
    return true;
}
4.将新的节点加入到双向链表的最后
void linkLast(E e) {
    final Node<E> l = last;
    final Node<E> newNode = new Node<>(l, e, null);
    last = newNode;
    if (l == null)
        first = newNode;
    else
        l.next = newNode;
    size++;
    modCount++;
}
​
运行结果:
[1, 2, 3]
[1, 3]
[8, 3]
3
 */

List集合选择

底层结构增删的效率改查的效率
ArrayList可变数组较低、数组扩容较高
LinkedList双向链表较高、通过链表追加较低
  • 如何选择ArrayList和LinkedList:

    • 如果我们改查的操作多,选择ArrayList

    • 如果我们增删的操作多,选择LinkedList

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

    • 在一个项目选择中,根据业务灵活选择,也可能这样,一个模块使用的是ArrayList,另外在一个模块事LinkedList

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值