看linkedlist部分底层代码的一些基础体会

首先从linkedlist最基本的元素结点node说起

问题1

为何node要设置成私有化的,这是java三大特性封装的优点。我们首先从调用者角度来思考问题。调用者在实际调用linkedlist类的时候,只关心这个list能否被创建(构造器),能否增删(add和remove),能否查找(遍历)。也就是说,他关心如何使用,而不是如何实现这个list中的这些方法。所以这些方法一般都是public,公开化的。调用者并不关心你底层的这个list是用结点实现的还是用数组实现的。所以这个结点类,作为内部类,他是私有化的。

从设计者角度分析,不同的数据结构有着不同的实现类型的结点,比如单向链表和双向链表的结点就不同,那么这个结点并不适合作为一个公用的属性,所以他作为一个单独数据结构的单独私有类,是合情合理的。另一方面,设计者也不需要让调用者知道list的结构单元是什么(也就是不想让调用者知道list底层是数组实现的还是结点实现的),反正他们只要会用就行了。这是一种黑匣子思想。而黑匣子思想也正是java封装特性的精髓。


那么从linkedlist的私有化方法说起





问题2

为何这些方法封装成私有化的

其实这个问题和问题1是一样的,因为我们呈现给调用者的是构造器,增删,遍历的方法,这些方法是公开化的,可以调用。但是这些方法具体如何实现的,调用者并不需要知道,我们也没必要让他们知道,所以我们封装成私有化,供linkedlist内部使用,并实现代码的复用性。

问题3

为何这些方法中创建的局部变量结点的引用是final的呢,我个人认为是这样的(可能不对,欢迎指正):

我们知道,linkedlist不像数组,我们想要查找元素,是比较麻烦的一件事情,数组可以按照下标index精确定位,而linkedlist只能从last或者first结点开始遍历向下查找想要找到的元素。那么这个遍历过程要确保的就是这个遍历路径是唯一的。那么这个路径的唯一性靠什么保证,那只能考结点的next和prev。那么既然next和prev是唯一性的,那么肯定是用final修饰。通俗来说,我们把结点当成目的地,next和prev当成路标。如果路标不唯一,那么你在去往目的地的过程中肯定会走错路,走错路必然到达不了目的地。如果next和prev不是唯一的,那么你在遍历过程中,万一这个结点的next和prev发生了变化,相当于产生了一个错误的岔路口,那么你肯定找不到你真正想要的那个结点。


栈可以用双端队列(双端队列用双向链表来实现)来实现(也就是说可以将Stack new成一个linkedlist),只需要对双端队列的队首进行push和pop操作就可以了。栈也可以用单向链表来实现。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LinkedList是Java中的一个双向链表,它实现了List和Deque接口。它的底层原理是基于链表实现的。 具体来说,LinkedList内部使用一个Node来表示链表中的节点,每个节点都包含了当前元素的值,以及指向前一个节点和后一个节点的引用。 当我们向LinkedList中添加元素时,它会创建一个新的节点,并将该节点插入到链表的末尾。如果链表为空,则新节点既是头节点也是尾节点。如果链表非空,则新节点成为新的尾节点,原尾节点的next引用指向新节点,新节点的previous引用指向原尾节点。 在插入和删除元素时,LinkedList不需要进行扩容操作,因为它没有固定的容量。相反,它只需要调整节点之间的引用关系即可。 LinkedList支持在任意位置插入和删除元素。在插入和删除元素时,LinkedList会通过修改相邻节点的引用关系来完成操作,而不需要像ArrayList那样移动其他元素。这使得在任意位置插入和删除元素时,LinkedList的性能更好。 然而,与ArrayList相比,LinkedList在随机访问元素时性能较差。由于LinkedList没有像数组那样连续存储元素,所以要访问特定位置的元素时,需要从头或尾开始遍历链表,直到找到目标位置。 总之,LinkedList底层原理是基于双向链表实现的,通过节点之间的引用关系来实现对元素的插入、删除和顺序访问。它在插入和删除元素时的性能较好,但在随机访问元素时的性能较差。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值