《LinkedList源代码阅读》

1、LinkedList适合场景:适合数据频繁添加删除操作,写多读少的场景

2、LinkedList的数据结构—双向链表(链表由若干个Node对象组成)

双向链表整体结构如下图所示:

first:头结点,它的前一个元素为空

last:尾结点,它的后一个元素为空

Node:链表的每个结点,Node的源码如下:

Node的属性:item代表数据域,next代表后一个结点的位置,prev代表前一个结点的位置

3、通过LinkedList源码分析常用的方法

3.1、添加元素

boolean add(E e):添加元素至尾部。在链表的末尾添加一个元素,并返回一个布尔值表示添加是否成功。将要添加的元素传给linkLast()方法,并调用这个方法。

首先,将最后一个结点的引用保存在l中,然后创建一个新结点newNode,将其前驱结点设置为l,后继结点设置为null,值为传进来的元素,将链表的last指向新结点newNode。判断最后一个结点是否为空,如果是,则说明链表为空,将first指向新结点newNode;否则,将最后一个结点的next指向新结点newNode。

 3.2、void addFirst(E e):添加新元素至链表头部(LinkedList特有的方法)

在addFirst()方法内调用linkFirst()方法,将传入的元素作为参数传入。

 将当前链表的头部结点保存在声明的变量里,然后创建一个名为 newNode 的新结点,将其前驱结点指向 null,后继结点指向 f,值为传入的参数 e。将链表的头部结点 first 指向新结点 newNode。如果原来的头部结点 f 为空,则说明链表原本是空的,因此将尾部结点 last 也指向新结点。否则,将原来的头部结点 f 的prev指向新结点。

 

 3.3、void addLast(E e):添加新元素值链表尾部(LinkedList特有的方法)

其基本思想与addFirst()方法相似,这里是将链表的最后一个结点赋值给l,然后创建一个新节点,将其前驱结点指向l,元素值为e,后继结点为null。将链表的最后一个结点last指向新结点newNode。

3.4、E get():遍历链表,查找指定位置的元素

将索引传给get()方法,先调用checkElementIndex()方法,然后调用node()方法来获取指定位置的节点,并返回该节点的元素。

调用checkElementIndex()方法来检查下标是否越界,如果下标越界,则会抛出异常。

先判断index是否小于size >> 1(链表长度的一半),如果是,从链表头结点开始遍历结点,直到找到指定位置的结点并返回该结点。如果index大于等于链表长度的一半,则从链表尾结点开始遍历结点,直到找到指定位置的结点并返回该结点。

 

3.5、E getFirst():获取链表的头元素(LinkedList特有的方法);E getLast():获取链表的尾元素(LinkedList特有的方法)

将链表中的第一个结点赋给f,再判断f是否为空,如果为空则抛出异常,否则返回f结点的元素值。

将链表中的最后一个结点赋给l,再判断l是否为空,如果为空则抛出异常,否则返回l结点的元素值。

3.6、int indexOf():查找链表中的指定元素的下标位置,如果不存在,则返回-1

定义一个index变量表示出现的次数。如果传入的下标为null,遍历链表并判断链表中是否也有结点值为null,若有,则返回当前的下标。如果不是null,则遍历链表并判断链表中是否也有结点值为o的参数,若有,则返回当前的下标。如果在遍历完整个链表后都没有找到符合条件的结点,则返回-1。

3.7、链表中删除元素的方法有多个,这里只讲其中的一种方法

(1)remove():删除链表中的头元素

(2)boolean remove():删除指定内容的元素

(3)remove(int index):删除指定位置的元素

(4)removeFirst():删除头元素

(5)removeLast():删除尾元素

调用了remove()方法中的removeFirst()方法。

将链表的头结点赋给f。如果链表为空,抛出NoSuchElementException()异常。如果链表不为空,调用unlinkFirst(f)方法删除头结点并返回被删除元素的值。

 

先保存结点的值和下一个结点的引用,将结点的值和下一个结点的引用设置为null,将链表的头指向下一个结点。如果下一个结点为null,则链表为空,将尾结点指向null。否则,将下一个结点的前驱指向null。然后让链表的长度减小,返回删除结点的值。

3.8、default void sort(Comparator c):按照Comparator比较器,将链表中的所有元素进行排序

sort()方法接受一个类型为Comparator比较器的参数,用于定义元素之间的顺序。先将列表转换为一个Object类型的数组,使用Arrays.sort方法对该数组进行排序,排序时传入了一个比较器,然后获取列表的迭代器,并通过for循环遍历数组,并将数组中的元素设置为列表中的元素。

3.9、Object[] toArray():将链表转换成数组(没有参数)

先创建一个长度为链表大小的数组,通过遍历链表中的每一个结点,把结点的值添加到数组中。

 3.10、T[] toArray(T[] a):将链表转换成数组(参数为数组)

该方法接受一个类型为T的数组作为参数,并将链表中的元素复制到该数组中。如果传入的数组长度小于链表的大小,则会使用反射来创建一个新的长度为链表大小的数组。如果传入的数组长度大于链表的大小,则会将最后一个元素设为null。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值