LinkedList基本方法源码解析

本文详细解析了LinkedList的数据结构和常见操作,包括其作为双向链表的内部实现、构造方法、Node类以及add、get和remove等关键方法的工作原理。LinkedList在添加元素时采用尾插法,get方法通过优化的查找策略提高效率,而remove方法则能有效地删除指定元素。了解这些基础知识对于理解和使用LinkedList至关重要。
摘要由CSDN通过智能技术生成

介绍

  linkedList的底层是双向链表,它继承了AbstractSequentialList,实现了List, Deque, Cloneable, java.io.Serializable。我觉得它相对于arraylist来说是比较简单的。我个人相对于linkedList还是使用较少的,所以就它的简单使用的方法做一个解析

属性

transient int size = 0;//链表大小
transient Node<E> first; //链表头部
transient Node<E> last;//链表尾部

构造方法

	//无参
	public LinkedList() {
    }
	//有参
    public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }
    //node类
    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;
        }
    }

从以上可以看出linkdList的初始化长度为0,并且他是无法设置初始化长度的。它的存储也是基于Node对象

常用方法

add(添加数据):使用的是一个尾插法

    public boolean add(E e) {
        linkLast(e);
        return true;
    }
    void linkLast(E e) {
        final Node<E> l = last; //尾部的数据
        final Node<E> newNode = new Node<>(l, e, null);//要插入的数据
        last = newNode; //更新尾部数据为此次插入的数据
        if (l == null)	//l为空的话就是首次插入
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }//相对于arrayList来说它的add方法是非常简单的 无需去对他进行扩容

get方法:

	
	public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }
    
    private void checkElementIndex(int index) {
        if (!isElementIndex(index))
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
    //此方法判断这个index是否在链表有效长度的范围之内
    private boolean isElementIndex(int index) {
        return index >= 0 && index < size;
    }
 	//这才是获取数据的一个方法
    Node<E> node(int index) {
        // assert isElementIndex(index);
        //在这里判断是从头还是尾开始一个查找 提高效率
        if (index < (size >> 1)) { 
            Node<E> x = first;
            //for循环从0开始查找对象 终止为index
            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;
        }
    }

remove:

    public boolean remove(Object o) {
    	//删除为null的node对象
        if (o == null) {
        //从头开始循环直到链表结束
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
    }
    
    E unlink(Node<E> x) {
        // assert x != null;
        final E element = x.item; //数据
        final Node<E> next = x.next;//下一个节点
        final Node<E> prev = x.prev;//上一个节点

        if (prev == null) {//只有是第一个节点的时候它的prev才会为null
            first = next;
        } else {
        /*让上一个节点的下一个节点指向当前节点的下一个节点,然后让当前节点的上一个节点为			   
        *null。就是当前节点与这个链表断了连接
        */
            prev.next = next;
            x.prev = null;
        }
		//这里就是尾节点了
        if (next == null) {
            last = prev; 
        } else {
        /*让下一个的上节点指向当前节点的上节点,然后将当前节点的下一个子节点=null
        * 不能只去改变上一个节点而不去改变下一个节点 如果说只改变上一个节点的指向而不去
        * 改变下一个节点 那么下一个节点的上prev指向还是当前节点 但是我们在后面以及将当前
        * 节点=null 那么我们下一节点在获取prev节点的时候就会产生一个空指针异常的错误
        */
            next.prev = prev;
            x.next = null;
        }
		//把这个数据置为null 方便GC进行回收
        x.item = null;
        size--;//将长度-1
        modCount++;
        return element;
    }

linkedList的话就看这几个方法,如果有方法没有讲解到位可以评论指出 谢谢各位
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值