集合-LinkedList源码分析

JavaSE基础知识(二十一)--Java集合(容器)之类LinkedList的源码分析(已修改) Java SE 是什么,包括哪些内容(二十一)? 本文内容参考自Java8标准 顺序访问列表的一个常用实现类: LinkedList 类声明: public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Clonea... 阅读详情

LinkedList是集合框架的一种数据类型.

继承关系:

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, 
    	Deque<E>, (双端队列)
    	    Cloneable, 
    	        java.io.Serializable
{

数据结构:

双向链表实现

特点:

优点: 增加和删除操作很快,不会涉及到数据的移动.
缺点: 访问速度较慢,需要遍历链表.

源码分析:

	/**
	* 链表的长度
	*/
	transient int size = 0;

    /**
	 * 指向链表的第一个节点
     */
    transient Node<E> first;

    /**
     * 指向链表的最后一个节点
     */
    transient Node<E> last;
//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;
        }
    }

1.构造方法

//空参构造
public LinkedList() {
}
//可传入一个集合c
public LinkedList(Collection<? extends E> c) {
    this();
    addAll(c);
}

2.添加方法

addAll(Collection c)

public boolean addAll(Collection<? extends E> c) {
        //调用addAll(size,c);// 将一个新集合添加到自己的后面
        // size 是当前集合的大小
        return addAll(size, c);
    }

    //添加新集合到指定下标index
    public boolean addAll(int index, Collection<? extends E> c) {
        //检测index是否合法
        checkPositionIndex(index);

        //将集合转为数组
        Object[] a = c.toArray();
        int numNew = a.length;
        //如果集合长度=0,直接返回false
        if (numNew == 0)
            return false;

        // pred 待插入位置的前驱节点
        // succ index位置的节点
        Node<E> pred, succ;
        //如果index == size,说明是将新集合插入到尾部
        if (index == size) {
            succ = null;
            pred = last;
        } else {
            succ = node(index);
            pred = succ.prev;
        }

        //遍历数组
        for (Object o : a) {
            @SuppressWarnings("unchecked") E e = (E) o;
            Node<E> newNode = new Node<>(pred, e, null);
            //如果待插入的位置是第一个位置
            if (pred == null) {
                //将first指向新节点
                first = newNode;
            } else {
                //设置pre的next指向插入的节点
                pred.next = newNode;
            }
            //pre向后移动
            pred = newNode;
        }

        //最后添加完,succ = null,说明是尾部添加
        if (succ == null) {
            // 在for循环结束时,pre指向的就是最后一个元素,后面没有数据
            // 将last指向pre
            last = pred;
        } else {
            // succ != null ,说明是从中间或者从前面添加数据
            // 将pre的next指向原集合的index位置的数据
            pred.next = succ;
            // 将原集合的index位置 的前驱节点指向pred
            succ.prev = pred;
        }

        //原集合的size + 新插入的数据长度
        size += numNew;
        //修改次数++
        modCount++;
        return true;
    }
//检查index是否合法
private void checkPositionIndex(int index) {
    if (!isPositionIndex(index)) {
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }
}

private boolean isPositionIndex(int index) {
     return index >= 0 && index <= size;
}
  • add(E e)
public boolean add(E e) {
     linkLast(e); 
     return true;
}

  • linkLast(E e)//尾部添加
void linkLast(E e) {
		//获取最后一个节点
        final Node<E> l = last;
        //new一个新节点,将该节点的前驱节点指向 l
        final Node<E> newNode = new Node<>(l, e, null);
        //last指向该新节点
        last = newNode;
        //如果l == null ,则说明是第一次添加,将first指向该节点
        if (l == null) {
            first = newNode;
        } else {
            //将最后一个节点l的next指向新节点
            l.next = newNode;
        }
        //长度++
        size++;
        //修改次数++
        modCount++;
    }
  • add(int index, E e):指定位置添加元素
//往指定位置index添加数据
public void add(int index, E element) {
    //检查index是否合法
    checkPositionIndex(index);
    //如果带插入的位置 == size,说明是尾部添加
    if (index == size) {
        linkLast(element);  //上面介绍过
    } else {
    	//传入待插入元素,并获取index位置元素
        linkBefore(element, node(index));
    }
}
//获取index位置元素
Node<E> node(int index) {
	 //为了提高效率,首先判断index 和size/2的关系
     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;
     }
}

  • linkBefore(element(待插入元素), node(index)(原链表元素));
void linkBefore(E e, Node<E> succ) {
        //获取原链表index位置节点的前驱节点pred
        final Node<E> pred = succ.prev;
        //创建一个新节点,将新节点的前驱节点指向pred
        final Node<E> newNode = new Node<>(pred, e, succ);
        //将原链表的元素的前驱节点指向新节点
        succ.prev = newNode;
        //如果pred == null ,则说明待插入位置为链表头部
        if (pred == null)
        	//将first指向新节点
            first = newNode;
        else
        	//否则原链表的前驱的后继节点指向新节点
            pred.next = newNode;
        //长度++
        size++;
        //修改次数++
        modCount++;
    }
  • linkFirst(E e) : 头部添加元素(头插法)
//头部添加数据
private void linkFirst(E e) {
		//获取first节点
        final Node<E> f = first;
        //创建新节点,将它的后继节点指向 f
        final Node<E> newNode = new Node<>(null, e, f);
        //更新first节点
        first = newNode;
        //如果f == null, 说明数据为空,将last指向新节点
        if (f == null)
            last = newNode;
        else
        	//否则将f的前驱指向新节点
            f.prev = newNode;
        size++;
        modCount++;
}

3. 删除方法

remove(Object) : 删除指定元素(第一个遇到的)

public boolean remove(Object o) {
	//如果对象==null
    if (o == null) {
        for (Node<E> x = first; x != null; x = x.next) {
             if (x.item == null) {
                  unlink(x);
                  return true;
             }
        }
    } else {
        //对象不为null
        for (Node<E> x = first; x != null; x = x.next) {
             if (o.equals(x.item)) {
                  unlink(x);
                  return true;
             }
        }
    }
    return false;
}
  • unLink(Node x): 将节点从链表中删除
E unlink(Node<E> x) {
    // 获取该节点的数据
    final E element = x.item;
    //获取该节点的next(后继节点)
    final Node<E> next = x.next;    
    //获取该节点的prev(前驱节点)
    final Node<E> prev = x.prev;
    
	//如果前驱节点 == null ,则说明该节点处于链表的头部
    if (prev == null) {
    	//将first指向待删除节点的下一个节点
        first = next;
    } else {
    	//不是头结点,则将当前节点的前驱节点的next指向待删除节点的下一个节点
        prev.next = next;
        //将待删除的节点的前驱置为null
        x.prev = null; //1
    }
    //如果后继节点 == null,则说明该节点处于链表的尾部
    if (next == null) {
    	//将last节点指向待删除节点的前一个节点
        last = prev;
    } else {
    	//不是尾节点,则将当前节点的后继节点的prev指向待删除节点的上一个节点
        next.prev = prev;
        //将待删除节点的next置为null 和 1操作一起 help GC
        x.next = null;
    }
    x.item = null; //将待删除节点数据置为null
    //长度--
    size--;
    //操作次数++
    modCount++;
    //返回删除节点的数据
    return element;
}
  • 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(Node f) : 将头结点从链表中移除
private E unlinkFirst(Node<E> f) {
		//获取头结点的数据
        final E element = f.item;
        //获取头结点的后继节点next
        final Node<E> next = f.next;
        //将头结点的数据置为null
        f.item = null;
        //将头结点的next置为null
        f.next = null; // help GC
        //更新头结点
        first = next;
        //如果next为null,则说明只有一个元素
        if (next == null)
        	//将last指向null
            last = null;
        else
        	//不止一个元素,将f.next的前驱节点指向null
            next.prev = null;
        //长度--
        size--;
        //操作次数++
        modCount++;
        //返回删除的节点的 元素
        return element;
    }

unlinkLast(Node l)

private E unlinkLast(Node<E> l) {
        // 获取最后一个节点的元素
        final E element = l.item;
        //获取最后一个节点的前驱节点prev
        final Node<E> prev = l.prev;
        //将数据置为null
        l.item = null;
        //将最后的节点的前驱指向null
        l.prev = null; // help GC
        //更新last节点
        last = prev;
        //如果前驱节点 == null,则说明只有一个元素,
        if (prev == null)
        	//将first置为null
            first = null;
        else
        	//将前驱节点的next置为null
            prev.next = null;
        //长度--
        size--;
        //修改次数++
        modCount++;
        //返回删除的节点的元素
        return element;
    }

4.获取元素

get(int index):

public E get(int index) {
        checkElementIndex(index);
        return node(index).item;
    }
    
//获取index位置元素
Node<E> node(int index) {
	 //为了提高效率,首先判断index 和size/2的关系
     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;
     }
}

5. 覆盖方法

public E set(int index, E element) {
		//检验index的合法性
        checkElementIndex(index);
        //获取index位置节点
        Node<E> x = node(index);
        //获取元素
        E oldVal = x.item;
        //更新元素
        x.item = element;
        //返回原来的数据
        return oldVal;
    }

自定义LinkedList

import java.util.NoSuchElementException;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: ZHANFEI
 * Date: 20-8-6
 * Time: 下午4:29
 */
class MyLinkedList<E> {

    //链表长度
    private int size = 0;
    //链表头部
    private Node<E> first;
    //链表尾部
    private Node<E> last;

     private class Node<E> {
        E val;
        Node<E> prev;
        Node<E> next;

        public Node(Node<E> prev,E val,Node<E> next) {
            this.prev = prev;
            this.val = val;
            this.next = next;
        }
    }

    //检测index是否合法
    private boolean checkIndex(int index) {
        if(index < 0 || index > size) {
            throw new IllegalArgumentException("Illegal index " + index);
        }
        return true;
    }

    //获取index位置的节点
    private Node<E> indexOf(int index) {
        if(index < (size >> 1)) {
            Node cur = first;
            //从前往后找
            for(int i=0;i<index;i++) {
                cur = cur.next;
            }
            return cur;
        } else {
            Node cur = last;
            //从后往前走
            for(int i = size -1; i > index; i--) {
                cur = cur.prev;
            }
            return cur;
        }
    }

    //往指定位置添加
    public void add(int index,E e) {
        checkIndex(index);
        if(index == size) {
            addLast(e);
        } else {
            //获取index位置的节点
            Node<E> indexNode = indexOf(index);
            //获取节点的前驱节点和后继节点
            Node<E> prev = indexNode.prev;

            //创建新节点
            Node<E> newNode = new Node<>(prev, e, indexNode);
            //若插入位置为头插
            if(prev == null) {
                first = newNode;
            } else {
                prev.next = newNode;
            }
            size++;
        }
    }

    //添加
    public boolean add(E e) {
        addLast(e);
        return true;
    }

    //头部添加
    public void addFirst(E e) {
        Node node = new Node(null,e,first);
        //第一个节点为null,链表为空
        if(first == null) {
            //将last指向node
            last = node;
        } else {
            //
            first.prev = node;
        }
        //更新first节点
        first = node;
        //长度++
        size++;
    }

    //尾部添加
    public void addLast(E e) {
        Node node = new Node(last, e, null);
        //最后一个节点为null ,则链表为空
        if(last == null) {
            //将first指向node
            first = node;
        } else {
            //链表不为空,last.next指向新节点
            last.next = node;
        }
        //更新last节点
        last = node;
        size++;
    }

    //删除第一个
    public E removeFirst() {
        if(first == null) {
            throw new NoSuchElementException();
        }
        Node<E> cur = first;
        //获取旧值
        E oldVal = cur.val;
        Node next = cur.next;
        //==null 则说明只有一个值
        if(next == null) {
            last = null;
        } else {
            next.prev = null;
        }
        first = next;

        cur.next = null;
        cur.val = null; //help GC

        size--;
        return oldVal;
    }

    //删除尾节点
    public E removeLast() {
        Node<E> cur = last;

        E oldVal = cur.val;
        Node<E> prev = cur.prev;

        //== null 则说明只有一个值
        if(prev == null) {
            first = null;
        } else {
            prev.next = null;
        }
        //更新last
        last = prev;

        cur.prev = null;
        cur.val = null; //help GC

        size--;
        return oldVal;
    }

    //删除
    public E remove(int index) {
        //获取index位置的节点
        Node<E> del = indexOf(index);
        E oldVal = unlink(del);
        return oldVal;
    }

    public E unlink(Node<E> del) {
        //获取数据
        E oldVal = del.val;
        //获取待删除节点的前驱和后继
        Node<E> prev = del.prev;
        Node<E> next = del.next;

        //若prev == null ,说明该节点是第一个节点
        if(prev == null) {
            first = next;
        } else {
            //将前一个节点的next指向它后一个节点(越过它)
            prev.next = next;
            //将该节点的next指向null
            del.prev = null;
        }

        //说明该节点是最后一个节点
        if(next == null) {
            last = prev;
        } else {
            next.prev = prev;
            del.next = null;
        }

        del.val = null; //help GC
        //长度--
        size--;
        return oldVal;
    }

    //删除指定元素
    public boolean removeObj(E e) {
        if(e == null) {
            for (Node cur = first;cur!=null;cur = cur.next) {
                if(cur.val == null) {
                    unlink(cur);
                    return true;
                }
            }
        } else {
            for (Node cur = first;cur!=null;cur = cur.next) {
                if(e.equals(cur.val)) {
                    unlink(cur);
                    return true;
                }
            }
        }
        return false;
    }

    //获取
    public E get(int index) {
        return indexOf(index).val;
    }

    //覆盖
    public E set(int index,E e) {
        //获取index位置的节点
        Node<E> eNode = indexOf(index);
        //获取值
        E oldVal = eNode.val;
        //设置为新值
        eNode.val = e;
        //返回旧值
        return oldVal;
    }

    //contains包含
    public boolean contains(E e) {
        Node cur = first;
        for (int i = 0; i < size; i++) {
            if(e.equals(cur.val)) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

    //toString
    public String toString(){
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        Node cur = first;
        while (cur != last) {
            sb.append(cur.val+", ");
            cur = cur.next;
        }
        sb.append(last.val);
        sb.append("]");
        return sb.toString();
    }

}

public class LinkedListTest {

    public static void main(String[] args) {
        MyLinkedList<String> list = new MyLinkedList<>();
        list.add("1");
        list.add("2");
        list.addFirst("0");
        list.addFirst("1");
        list.add("3");
        list.add("4");
        list.addFirst("2");
        list.addFirst("3");

        System.out.println("添加元素之后: "+list);
        list.remove(2);
        list.removeObj("1");
        System.out.println("删除: "+list);

        list.removeFirst();
        list.removeLast();
        System.out.println("删除头和尾"+list);

        System.out.println("是否包含: "+list.contains("1"));

        System.out.println("获取index=1: "+list.get(1));

        System.out.println("更新0号位置的值: "+list.set(0, "s"));
        
    }
}
从源码分析LinkedList集合 从源码分析LinkedList集合简介构造方法LinkedList()LinkedList(Collection<? extends E> c)常用方法int size()E getFirst()E getLast()E removeFirst()E removeLast()void addFirst(E e)void addLast(E e)boolean contains(Object o)int indexOf(Object o)int lastIndexOf(Object o)向列表中添 阅读详情

相关推荐

君正T31x metartc集成测试

metartc为国内杨大侠部分开源的一款用于嵌入式领域webrtc库,它与谷歌官方webrtc相比,编译到君正平台的可执行文件仅有5M即可实现webrtc的通信。1. 目前实现的是基于开源版v5.0-b0版本做的简单修改,官方的好几个版本都多少缺点东西,我这里给整理了一下。目前是局域网连接的webrtc,后续尝试走stun和turn试一下NAT穿越的效果。

fsmpeg的博客 3159

LinkedList源码分析(超详细)

先学 ArrayList 再学 LinkedList,面试官:“这小子,有两把刷子。”

一条咸鱼的博客 1152

LAMMPS in文件详解:从零开始手把手教你配置金属分子动力学模拟

本文详细解析了LAMMPS in文件的配置方法,手把手教你完成金属分子动力学模拟的全流程。从软件环境准备、势函数选择,到使用Materials Studio构建模型、编写in文件进行能量最小化与系统弛豫,再到实施单轴拉伸生产模拟并提取应力应变数据,最后通过Python和OVITO进行结果分析与可视化,提供了完整的实战指南和常见问题排查技巧。

weixin_28475533的博客 529

Java集合之LinkedList源码分析

概述 LinkedLIst和ArrayLIst一样, 都实现了List接口, 但其内部的数据结构不同, LinkedList是基于链表实现的(从名字也能看出来), 随机访问效率要比ArrayList差. 它的插入和删除操作比ArrayList更加高效, 但还是要遍历部分链表的指针才能移动到下标所指的位置, 只有在链表两头的操作能省掉移动, 如add(), addFirest(), removeL...

weixin_30611509的博客 194

电力电子技术进阶:从基础到实战的完整学习路径

本文系统阐述了电力电子技术从基础到实战的完整学习路径。首先解析了电力电子作为“电能魔术师”的核心作用,随后深入剖析了数学工具、电路电磁场与半导体器件三大基础支柱。文章重点讲解了DC-DC、DC-AC、AC-DC等核心变换拓扑,并探讨了从经典PID到现代模型预测控制(MPC)的控制策略。最后,分享了硬件设计、软件调试、电磁兼容(EMC)等实战经验与前沿趋势,为学习者提供了清晰的进阶指南。

weixin_29204205的博客 447

Qt (高仿Visio)流程图组件开发(一) 效果展示及基本开发框架构思

最近因为工作原因需要使用Qt开发一个类似于Visio的流程图组件,需满足基本的流程图功能,图元类型可自定义扩展,不同图元存有各类自定义数据,可以保存为xml文件,可以读取xml文件生成流程图等等。

qq_43793182的博客 1万+

【Java集合源码剖析】LinkedList源码剖析

LinkedList简介 LinkedList是基于双向循环链表(从源码中可以很容易看出)实现的,除了可以当做链表来操作外,它还可以当做栈、队列来使用。 LinkedList同样是非线程安全的,只在单线程下适合使用。 LinkedList实现了Serializable接口,因此它支持序列化,能够通过序列化传输,实现了Cloneable接口,能被克隆。 LinkedList源码剖析 LinkedList的源码如下(加入了比较详细的注释):

兰亭风雨的专栏 1万+

AI 实战篇 |基于 AI开放平台实现 人脸识别对比 功能,超详细教程【附带源码】

本篇文章来学习一下怎样使用 Unity实现简单地人脸识别 功能。 关于人脸识别,我们可以选择很多平台的SDK接入Unity来实现人脸识别的功能。

努力前行,总会成为自己心中的那道光 5万+

一文读懂,java list集合详解及arraylist,linkedlist集合底层源码分析

Collection集合概述是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素JDK 不提供此接口的任何直接实现.它提供更具体的子接口(如Set和List)实现创建Collection集合的对象多态的方式具体的实现类ArrayListCollection集合常用方法方法名说明添加元素从集合中移除指定的元素根据条件进行移除清空集合中的元素判断集合中是否存在指定的元素判断集合是否为空集合的长度,也就是集合中元素的个数List集合的概述。

m0_58975186的博客 1004

如何合理评估信号过孔的残桩效应--Via Stub

设计中,之所以会去考察信号过孔的残桩效应(Via Stub),是因为它的存在导致了不需要的频率谐振,当这些谐振出现在所关注的信号通道的插入损耗中时,就会引发较为严重的信号完整性(SI)问题,那么Via Stub到底是如何引发SI问题的呢?

一只豌豆象的博客 4467

电磁阀颤振工作原理

颤振 颤振,弹性结构在均匀气(或液)流中受到空气(或液体)动力、弹性力和惯性力(见达朗伯原理)的耦合作用而发生的大幅度振动,它是气动弹性力学中最重要的问题之一。 随着机电液一体化技术的发展,电液比例控制技术的应用越来越广泛。电液比例控制系统范围较广,在液压传动与控制过程中,系统能够接受模拟信号或数字信号,使输出的流量或压力连续成比例地变化,都属于此类。该控制系统的优点是充分利用了液压控制与电气控制的长处,即功率传递靠液压,信号处理靠电气的优化措施。 电液比例控制原理与要求 液压控制系统中两个最重要的被控参数

小幽余生不加糖 1万+

List之LinkedList集合源码分析

List之LinkedList集合源码分析

命硬的博客 408

大模型之Spring AI实战系列(一):基础认知篇 - 开启智能应用开发之旅

Spring AI 是一个轻量级开源框架,旨在简化 AI 模型在企业级 Java 应用中的集成与管理。它提供了跨多个 AI 服务提供商的便携式 API,支持聊天、文本转图像、嵌入式模型等多种功能,并兼容主流的 AI 模型提供商如 OpenAI、Google 等。Spring AI 的核心功能包括结构化输出、向量数据库支持、工具/函数调用、可观察性、文档摄取 ETL 框架、AI 模型评估等。

寻道AI,探索AI无限可能! 6368

Java集合:ArrayList的使用及源码分析、Vector和LinkedList的使用

ArrayList的使用及源码分析

qq_59212867的博客 303

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

死磕 java集合之LinkedList源码分析

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34249678的博客 70

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

java集合-ArrayList/Vector/ LinkedList源码分析

以上策略不适用,编者重写了else语句,会直接选择在DEFAUIT_CAPCITY和minCapacity中最大的那个(因为需要满足存储的需求),可以看到这里的DEFAUIT_CAPCITY被初始化为一个长度为 10 的数组。用crtl+b步入add函数,if语句用来判断位置是否已满,若相等则说明已满,需要用grow()扩展,接着就是赋值和将size++,若长度足够,则不需要调用grow()没有被显式设置,扩容时的增长量将与当前容量相同,会使用推荐的增长策略(通常是。引用,指向新的数组,完成扩容操作。

2301_81088399的博客 894

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

java linkedlist源码分析_java集合系列之LinkedList源码分析

java集合系列之LinkedList源码分析LinkedList数据结构简介LinkedList底层是通过双端双向链表实现的,其基本数据结构如下,每一个节点类为Node对象,每个Node节点包含该节点的数据和分别指向前一个前一个和后一个节点的引用。LinkedList内部维护两个成员变量first和last,分别指向链表的头节点和尾节点(接下来的成员变量介绍中会提到)。由于LinkedList基...

weixin_28961565的博客 205

【java集合】LinkedList源码分析

LinkedList是一种基于链表实现的集合类,也是经常使用到的集合。其特性归纳如下: 特性 值 是否顺序存储 顺序 是否可重复存储 可以 是否可存储null 可以 是否线程安全 非线程安全 LinkedList的属性首先列举一下ArrayList主要属性,方便大家理解和本文的说明: 属性 说明 first 链表的头部 last 链表的尾部

I am a coder 355

LinkedList集合源码分析

LinkedList 使用双向链表来存储元素,不需要连续的内存空间来存储元素,所以不需要扩容。一般作为队列,直接操作头部和尾部。支持存储或删除相同的元素,且支持存储null,存储的元素有序。存在相同多个值是,会删除靠近头结点的值。查找元素只能遍历查找,效率慢O(n),删除,插入快O(1)。根据元素值查找,只能从头结点开始遍历。如果根据 位置查找,会从距离头结点或尾结点近的一方开始遍历。不是线程安全的。

weixin_45278293的博客 560

【死磕 Java 集合】— LinkedList源码分析

【死磕 Java 集合】— LinkedList源码分析 问题 (1)LinkedList只是一个List吗? (2)LinkedList还有其它什么特性吗? (3)LinkedList为啥经常拿出来跟ArrayList比较? (4)我为什么把LinkedList放在最后一章来讲? 简介 LinkedList是一个以双向链表实现的List,它除了作为List使用,还可以作为队列或者栈来使用,它是怎么实现的呢?让我们一起来学习吧。 继承体系 通过继承体系,我们可以看到L...

wangzhipeng47的博客 185

List集合了解及arrayList、LinkedList等实现类的使用-部分源码分析

List集合继承与Collection接口

zf_csdn123的博客 299

【初探Java之路 六 】集合1-ArrayList和LinkedList的使用与源码分析

ArrayList是Java集合框架中的一个动态数组实现。它就像一个会自动扩展的魔法背包,当你往里面塞更多东西时,它会自动变大。//学号//姓名//年龄//居住地return sid;return age;/*1:用输出语句完成主界面的编写2:用Scanner实现键盘录入数据3:用switch语句完成操作的选择4:用循环完成再次回到主界面*///创建集合对象,用于保存学生数据信息//用循环完成再次回到主界面//用输出语句完成主界面的编写。

z17711802963的博客 1693

集合框架之LinkedList源码分析

集合框架之LinkedList源码分析 一、简述 LinkedList是Java集合中一个全能的结构,底层采用了双向链表结构。和ArrayList也支持空值和重复值,但是使用链表实现,在插入元素效率高,但是遍历查询效率比较低。 LinkedList是非线程安全的集合类,并发环境,多线程操作LinkedList,会引发不可预知的错误。 优点:底层是链表,所以增删只需要移动指针,效率很高,不需要批量扩...

学习和工作总结,共勉! 436

[Java 集合] LinkedList源码分析

[Java 集合] LinkedList源码分析 源码基于jdk 11 LinkedList是一个以双向链表实现的List,它除了作为List使用,还可以作为双端队列或者栈来使用 一、属性 //元素的个数 transient int size; //头节点 transient LinkedList.Node<E> first; //尾节点 transient LinkedList.Node<E> last; private sta

zhangsan_716的博客 217
上一篇: 集合-ArrayList源码分析
下一篇: Java简单计算器(栈实现)
Java-fly
博客等级 码龄9年 13粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值