linkedList小记

本文详细解析了LinkedList的内部结构,包括其继承关系、关键属性、构造函数及常用方法。通过源码级解读,揭示了节点链接、插入、删除等操作的具体实现,为读者提供了一个全面的LinkedList学习指南。
摘要由CSDN通过智能技术生成

linkedList小记

linkedList继承关系图

linkedList继承关系图

field属性

   	//集合大小
	transient int size = 0;
	//上一个节点
    transient Node<E> first;
  	//下一个节点
    transient Node<E> last;

Node

 private 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;
        }
    }

构造函数

	public LinkedList() {
    }
    public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }

常用方法

私有方法,用于内部使用,参考jdk原码,不完全一样

/**
     * 将该元素放在第一个位置
     * @param e
     */
    private void linkFirst(E e) {
        final Node<E> f = first;
        // 前驱为空,值为e,后继为f
        final Node<E> newNode = new Node<>(null, e, f);
        first = newNode;// first指向newNode
        // 此时的f有可能为null
        if (f == null)// 若f为空,则表明列表中还没有元素
            last = newNode;// last也应该指向newNode
        else
            f.prev = newNode;// 否则,前first的前驱指向newNode
        size++;
        modCount++;
    }


    /**
     * 最后面添加节点
     * Links e as last element.
     */
    private void linkLast(E e) {
        final Node<E> f = last;

        //前驱为之前的last
        final Node<E> newNode = new Node<>(f, e, null);

        last = newNode;// first指向newNode
        // 此时的f有可能为null

        if (f == null)// 若f为空,则表明列表中还没有元素
            first = newNode;// last也应该指向newNode
        else
            f.next = newNode;// 否则,前first的前驱指向newNode
        size++;
        modCount++;
    }
	
	//删除第一个节点
    private E unlinkFirst(Node<E> f) {
        final E element = first.item;

        Node next = f.next;
        first = next;

        //帮助gc回收
        f.item=null;
        f.next=null;
        if(next==null){
            last=null;
        }else{
            next.prev=null;
        }

        size--;
        modCount++;
        return element;
    }
	
	//删除最后一个节点
    private E unlinkLast(Node<E> l) {
        E e = l.item;
        Node<E> pre = l.prev;

        last = pre;
        l.prev=null;
        l.item=null;

        if(pre==null){
            first=null;
        }else{
            pre.next=null;
        }
        size--;
        modCount++;
        return null;
    }

	/**
     * 在某个元素之前添加元素
     * @param e 新增的元素
     * @param succ 之前的元素
     */
    private void linkBefore(E e, Node<E> succ) {
        Node<E> prev = succ.prev;
        Node<E> newNode = new Node<>(prev,e,succ);
        succ.prev=newNode;
        if(prev==null){
            first=newNode;
        }else{
            prev.next=newNode;
        }
        size++;
        modCount++;
    }
	
	/**
	 * 删除某个节点
	 *
	 */
    private E unlink(Node<E> e) {
        E item = e.item;
        Node<E> prev = e.prev;
        Node<E> next = e.next;
        if(prev==null){
            first=next;
        }else{
            prev.next=next;
            e.prev=null;
        }

        if(next==null){
            last=prev;
        }else{
            next.prev=prev;
            e.next=null;
        }
        e.item=null;
        size--;modCount++;
        return item;
    }
	
	/**
	 * 根据下标查找节点
	 *
	 */
    private Node<E> node(int index) {
        // assert isElementIndex(index);
		//这一步挺不错的,根据下标对的位置决定从头还是从尾开始遍历,当然下表需要校验
        if (index < (size >> 1)) {
            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;
        }
    }

常用方法实现

    /**
     * 大小
     */
	@Override
    public int size() {
        return size;
    }
	/**
     * 头部新增元素,调用上面的linkFirst
     */
    @Override
    public void addFirst(E e) {
        linkFirst(e);
    }

	/**
     * 尾部新增元素,调用上面的linkLast
     */
    @Override
    public void addLast(E e) {
        linkLast(e);
    }

	//删除头
    @Override
    public E removeFirst() {
        Node<E> f = first;
        if(f==null) throw new NoSuchElementException();
        return unlinkFirst(f);
    }
	//删除尾
    @Override
    public E removeLast() {
        Node<E> l = first;
        if(l==null) throw new NoSuchElementException();
        return unlinkLast(l);
    }
	
	//根据下标获取元素
    @Override
    public E get(int index) {
        ArrayUtils.checkIndex(index,size);
        Node<E> x = node(index);
        return (E)x.item;
    }
	//获取头
    @Override
    public E getFirst() {
        if(first==null)throw new NoSuchElementException();
        return first.item;
    }
	//获取尾
    @Override
    public E getLast() {
        if(last==null)throw new NoSuchElementException();
        return last.item;
    }
	
	//删除尾
    @Override
    public E remove() {
        Node<E> node = last;
        if(node==null)throw new NoSuchElementException();
        unlinkLast(last);
        return node.item;
    }
	
	//根据下标删除
    @Override
    public E remove(int index) {
        ArrayUtils.checkIndex(index,size);
        Node<E> node = node(index);
        unlink(node);
        return node.item;
    }
	/**
	 * 迭代器实现
	 */
 	@Override
    public Iterator<E> iterator() {
        return new Itr();
    }


迭代器

 private class Itr implements Iterator<E>{

        int cursor = 0;       // 返回下一个元素的下标
        int lastRet = -1; // 最后一次操作元素的下标

        // prevent creating a synthetic constructor
        private Itr() {}

        @Override
        public boolean hasNext() {
            return cursor!=size;
        }

        @Override
        public E next() {
            ArrayUtils.checkIndex(cursor,size+1);
            lastRet = cursor;
            cursor++;
            Node<E> node = node(lastRet);
            return node.item;
        }

        @Override
        public void remove() {
            ArrayUtils.checkIndex(cursor,size+1);
            if (lastRet < 0)
                throw new IllegalStateException();
            unlink(node(lastRet));
            cursor=lastRet;
            lastRet=-1;

        }
    }

linkedList学习笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值