00:00
好了,那咱们就继续再往下吧,同学们,咱们再往下,咱们。干什么呢?哎,我们得看看这个link list的这个集合啊,就是刚才这个继承结构图里边就是它对吧,那这个双向列表是长什么样的,我们来把它图画一下各位啊,双向列表。呃,双向列表当中啊,它的元素啊,基本单元还是节点。那假如说这个呢,就是我们所说的内存,那么双键列表是这样的。啊,就是双向列表上面。双向链表上面上啊,基本的单元还是节点node。啊,还是几点弄的。那么这个节点node呢?可能由三部分组成。啊,这个节点。三部分组成,为什么说为三部分组成呢?它呢里边有数据。有数据。
01:00
肯定啊,你集合不就是往里面存数据吗?对吧,哎,这是数据啊,然后呢,这个节点呀,它含有下一个节点的内存地址。同时它又含有什么呀,上一个节点的内存地址。明白吗?嗯,来。就是这一个节点啊。它里边有什么呀,有上一个节点的地址。有数据啊,同时它这个节点还有什么呀,下一个节点对象的内存地址各位。啊,不知道能不能看明白啊,就是这一个节点,它有三部分组成。啊,你比如说你这是这是一个。是吧,哎,这是一个啊。这个呢,节点呢,也是由什么呀,三部分组成。
02:01
啊,三部分组成来。这是数据。这个0X1234是谁呢?是这个节点,是这个对象,就下边这个对象。这个对象啊,它的一个内存地址。这样吧,画到这吧啊。啊,如果你不看这个对吧,它就是单向的。你这边可能还有一个节点。往往往往这往这画吧,画这画这得了。画得了啊,来。我这画一个。它每个这是一个节点啊,这是一个节点,这是个节点,这是个节点,这个节点。嗯,对。大致的画一下啊,然后这个节点呀。它含有上个节点的对象内存地址,这个节点的内存地址假如说是0X5555吧。
03:05
啊,大概是这个意思啊。谁的地址呢?是这个节点的地址。就是我当前节点既含有你下个节点内存地址。又含有你上一个节点内存地址,双向呢,双方向的通过这儿往这儿找能找到,通过这儿往回逆着找也能找到啊,也能找到,那么这块呢,这个地址呢,我就随便画一个了啊,比如说是。0X2222。哎,那这个是谁的呢?怎么着吧?所以啊。这样。我这靠靠啊。这个意思。双向链表。
04:01
来这个呢,我往这一点。啊,这个呢,去指向谁呀他。你这个位置的地址呢,就是你上个对象的地址了。这个意思啊。就是说你这个节点呀,一个节点。还有什么呢?我们上一个节点的内存地址,同时又含有下一个节点内存地址,通过这个方向去找能找到,顺着找、逆着找都能找到,这是双向的。啊,那将来这个是尾极点,那你可能就是个none了。啊,如果你这个是个头节点,那你头节点这块可能就是个囊了。这样的。啊,这是中间的这个节点是吧,可能会有多个啊,这个是一个双向链表,各位啊,来叫做29。
05:06
双性链表啊。来这个大概瞅一眼,要比这个单价列表要复杂一些,是不是啊,但比单列表复杂一些,那如果是这样的话,我们看一下瞅一眼啊,看它确实是不是这种情况,来我们这块都给它关了,回来之后我们collection这块呢,我们看一下这个叫做link list,就这个呗。对吧,叫link list的这个集合啊,我们点过去吧,就这个呗,我点这个I是吧,点过去这个link list集合呢,我们 CTRLf12,然后呢,我们找一下找找一找这个构造方法呗,构造方法你看这是不是个构造方法呀。对吧,无参的是不是,哎,我们看一看啊,它这个link list集合,这个是无参的,下边这是有参数的构造方法,来看一看啊,它默认值size是多少,是零对不对,每里边存储的元素个数是零,然后接下来呢,在这有一个first,看见没有?有一个属性叫first是第一个节点,Last是最后一个节点吧。
06:03
第一个节点是空的,这边是默认值是空,因为你调无参数的构造方法的时候,它的默认值是空,它的默认值也是空,就第一个和最后一个都是空。就第一个节点吗?这不最后一个节点吗?是不是,哎说指针指向第一个节点,指针去指向最后一个节点。呃,为什么上一个尾节点和下一个。没我看看。我画的不一样吗?指向零。错了啊。错了,各位。这个地方是0X123的指向这个对象是吧。这是0X1234啊。嗨。感谢啊感谢,这就错了,确实错了。哎,这样。这样就对了吧,没毛病吧,这保存内存地指向它嘛,这个对象是0X1234嘛。
07:08
是不是,然后这个位置指向它,它就是0X1234,然后呢,它呢去指向它,它是0X222对着呢,这个呢,就指向它是零五。没毛病吧?是不是就这有点问题是吧。佳辉是说这个吗?佳慧,应该说的是这个吧。这个地址。不是这个对象的地址吗?是吧,那这个地址。是不是这个对象的地址啊。这个地址是这个对象的地址,然后这个地址是保存的什么呀,保存的啊,保存的是这个对象,这个地址对着呢对着呢啊对佳辉说的对啊,这这错了。
08:02
画错了啊,来继续看啊,我们这个link list这边里边是size是零,然后这是first,这是last first是空,Last是空,你看指针指向第一个基点,指针去指向最后一个基点,第一个基点是空的,最后一个基点是不是也是空的呀?对吧,哎,说构造一个空的list。对吧,是list集合好了,那我们可以看一看这里面有没有这个叫I的方法,往这个link list里边加元素是怎么加的,行不行。我们捋一下啊。我觉得这个图也可以画一下啊,来这个关了。再重新打开。嗯,保存一份啊,我们叫做D29的。Link内存图。行吧,内存图啊,然后呢,假如这就是那个。叫什么?叫做link list。Link list集合啊,这个link list集合首先它有几个属性啊。
09:06
有这么几个属性,Size一个属性。是不是?有last吧?那这个图这样画吧,各位。画一个Java虚拟机挂大点。假如说现在啊,我们在这里就把这个图画一下吧,行吧,就把这个图画一下,各位啊,就这个图了,Link list t01这个图。我画的画画的大一些啊,比如说这块呢,咱们。这样画一下。看一下啊,读源代码这个不太好读JVM。然后有方法区呗。那就不用画这个方下去了,实际上就给一块空间就得了啊,然后呃,这个假如说这就是堆吧,啊,这就理解成我们是堆啊,堆内存,然后再往下的话,我们这儿应该有一个什么呀,叫做占。
10:01
赞啊,来。好,那这块呢,咱们给它删了。首先第一个它会进行类加载,会把这些类呢,这个类呢,是不是这个类都装载进去,我就不写了啊,直接是闷方法进来,所以呢,这边应该是我们的方法战争了。画一下啊。哪有问题你就说话啊,那这叫闷方法什么呀,战争好了,那么闷方法战争过来之后呢,他这边怎么做呀,各位。嗯,应该是说先一个link是不是。Link list的这个集合,那new的话,那就new出来呗,假如这就是link list啊,就大了啊,就这个啊。好。哎。这样吧。Linked list集合对象。说谁呢?这个图咋样,这么画?来link list集合对象啊扭出来,那这个集合里边有一个。
11:05
什么呢?调的是无参数库的方法吗?然后这边不是有一个size是零。是不是这个size呢?可以简单画一下。这回就行了。来这边有一个size。他给的值是一个零。是吧,好。那么接下来呢,我们这个程序呢。再往下,这里边有一个什么呀,那头节点。就是第一个节点是,那最后一个节点是none。那这个是个什么东西。现在是空吗?还没有值,没有值我就不画了,各位啊。就不画了,行吧,想着点啊,在这里边有有两个,有两个none啊,一个是first,一个是last。就first表示第一个节点,这边是最后一个节点。
12:03
那这个程序呢,现在就到哪儿呢,到这儿了。这个对象内存给了list。就是个局部变量。等于这个零。等于零,X11就随便写吧。他呢,就指向了这个对象。是不是,然后接下来呢,我们list调I的方法,那就看这个link link list这个集合里边I的方法。走了啊,注意看啊。过去。这个爱的方法呢,它在这调了一个叫link link last,把E参数传进去了。对吧,调这个link last这个方法,At方法啊,把这个E传给了这个方法,我们重点是不看这个方法呀,点过去。那点过去之后呢,接下来大家看看这个代码能不能看懂啊,这个可能耗费的时间比较长一些,画内存图画到这儿了,现在你要注意啊,紫色的是成员变量。
13:07
是成员变量啊,或者是实例变量,各位啊,就现在这。哎,画上也行。这个是那个no啊。No。First。只不过他现在是那。啊,然后呢,还有一个叫做什么呀,叫做。Not last也是那。Not the last。那样的话,其实就就代表没有啊。我直播画出来,按说不应该画出来啊来。First now last now。这都是实例变量,然后呢,这个程序是把last赋给了个局部变量L。
14:02
但是上来这个是呗,各位。是吧?那这个局部变量吧。这是link吧?是不是那调这个方法各位应该在哪啊,在这是不是压站啊。对不对。Link方法战争。我刚才其实都省,省了省了几步,各位啊,省了几步。这个方法。调用这有个E,这个E是谁?就是我们调I的方法的时候,传进去的这个A。调这个方法。这是构造,构造方法紧接着往下执行,它是I的加元素,这个元素就是那个A。对吧,调这个方法,那这个方法进来,进来之后呢,这里有一个什么呀。
15:03
No l。是空吧?是不是空个位。L啊。等于first。这个。啊,等于none。然后紧接着呢,这个程序是怎么走的,他拗了一个新的节点,各位。看见了吗?New一个node,然后这个node呢,把L作为参数传进去了。然后呢,把E放到这个位置上。是吧,后边又一个none,这是个什么东西,这是一个构造方法,但是这个类是个内部类,各位。内部类啊,Link的list的这个集合里边有一个类叫node,我们点过去,大家看这个node这个类是不是有item,还有next和上一个,这是下一个吧,这是不是上一个呀?当前这个节点有下一个节点的内存地址,同时这个节点又有什么上一个节点内存地址吧。
16:21
是吧,因为我们是加一第一个元素,各位啊,加第一个元素。大家想想啊。他你这个对象的时候,是不是调这个构造方法,这个构造法有这个参数,有这个参数,还有这个参数,这参数付给了这个参数付给了这个item是不是,然后next付给了这个next,然后呢,这个上一个就付给了上一个,这个类是不是一个静态的一个内部类,你看class前面加static是一个静态的一个内部类,对吧?内部类当中有三个属性,一个是数据,一个是上个节点内下个节点内存地址,一个是上一节点的内存地址。来,我们再回来啊,再回来看叫什么呀,叫爱的方法来过去啊,点一下这个link last这个方法,这个方法过来,首先这个是不是等于空,这是空啊,这L是空,现在对应我们的内存图就是这样一个图。
17:11
然后接下来怎么做呢?他new了一个什么呀,Node付给了new node,也就是说将来在这它有一个什么。就没了。叫node new note。那么这个new node new node啊,新的节点后边应该是有个内存地址是吧,这个地址去指向了谁?去指向了我们new的一个节点对象,而这个节点对象会在我们的堆内存当中开出来。开出来之后,这个对象有三部分组成。哪三部分组成呢?好看看啊。
18:00
L是不是就是它。是。对吧,这个E是不是E呀,这是不是也是空啊,所以这个时候new的这个节点。上一个元素是空。对不对,这是数据下元子是空,也就是说它刚刚创建出来的时候,这个位置实际上是把L啊,他把L传过来了,各位啊,我不知道大家这个图能不能看明白,他把L就传过来了,放这儿了,那L传过来实际上L是空啊。所以这个时候这个位置它就是空。然后呢,这个位置呢。他就是那个数据。A。因为调I的方法把这个A传进去了。过来是不是这就是那个数据嘛。好,那这个里面存储的其实就是。A。然后他紧接着在我们这个内存图上,刚才大家应该是看到了我们这个艾的方法叫link last这个方法第三个参数next是什么呀?是none。
19:10
那么这一块它传的也是一个捺好了。那么接下来呢,我们link last这个方法new出来之后,这个对象内存地址付给了new node。是吧,好,大家看啊,嗯,New node。好了啊,那么接下来这个程序怎么走的?继续往下看,它new node等于last是什么意思?就这个last这块有东西的各位。明白吗?删掉。这里边儿存什么,各位?你有那么多吗?扭出来之后,把它放到了这个last这一块。对吧,然后让他去干啥去指向了他。
20:00
哎,有意思。你看这个程序啊,怎么走的。New node,这不new出来的吗?这个对象的内存地址付给了new node new node就是这个NN嘛,NN等于0X230X23,最后这个newno又付给了,这个叫last,看见没有?赋给这个last是什么意思啊?就表示last这个变量里边保存一个内存地指向这个对象,这个对象就是last最后一个,然后紧接着这个程序怎么走的,看看他说如果L等于空。好,我问大家,L现在是不是确实等于空?如果L等于空的情况下,它这个程序的走法是new note又付给了first。有意思。那first现在是空的。那么也就是说,这个妞妞的内存地址会再付给谁?这个。那这样的话,First其实指向的也是这个。
21:00
几点?其实我觉得这个说的有道理,为什么呢?这个指针指向第一个元素,这个指针是指向最后一个元素的,对吧?当你添加第一个元素的时候,其实内存的内存的一个内存图就是这样的。在你link list的这个集合当中,你有一个指向第一个节点的指针,有一个指向最后一个节点的指针,因为你只有一个元素,第一个元素就是。最后一个元素,最后元素就是第一个元素。好,那如果各位再去调这个爱的方法呢?再去调这个I的方法,放一个B进去的话,那么这块这个方法是不是又进来执行。对吧,那么此时这个last付给了这个L,这个L是啥,各位。我们再顺着走,各位啊,顺着走。他把last付给了谁?付给了L,行了,Last是这个,这里边是0X23。
22:03
让他。附到了这个位置上。那你一旦附到这个位置上,这说明什么?说明我们这个L现在是不是指向了这个对象。肯定是指向这个对象的。注意啊,注意。我可能会需要画一个过程,这个图没法给大家完完整保留下来啊,需要画一个过程好了,那么加第二个元素的时候呢,他把这个叫做last赋给了L,我们再审一遍啊。就等于说呀,又在这儿又有个新的局部变量,里边保存0X23对吧,Last附上去的,然后指向它,那么接下来这个程序怎么走的说又new了一个新的node。这个新的节点实际上第一个是L,第二个是数据,第三个是那。来,我们把这个几点溜出来。这个进来拧出来之后呢,等于是一个新的呀,会附上一个新的地址吧,Newno是不是新的地址啊。
23:06
对吧,来,我们再再来啊。你一个node好了。新的几点。好画出来,画出来之后呢,接下来我们是怎么做的啊,第一步是。这个删了吗?各位,这个删掉就行了啊。嗯,现在进来第一件事就是这个做了last付给了L。L有值了啊,0X2指向它,那么接下来我们这个是怎么走的,New个node,那new node是不是应该是新的地址?指向这个对象吗?指向这个对象吗?各位。
24:01
是吧,New node等于新的啊0X45吧,假如说0X5啊,那0X45呢,应该是他。去指向谁呢?指向他呗。对吧,哎,那颜色变一下啊,颜色变一下。那这个节点里边存什么东西了呢?肯定往这儿存了个啥B,没得说。对吧,因为我们上面这个程序往里面加了个B啊。那加了B之后呢,L是放在上一个,这个是nu,那么也就这个位置实际上是nu。对吧,这个位置是L。L是0X23,那这个地方是不是就是0X23,各位。你想想,它是不是把L放到这儿了?这是不是上一个L,是不是等于last last是不是付给了L?原先这个LA0X23付给了这个LL是0X23,把0X调构造方法,把这个L传进来这个构造方法,所以这地方也是0X23,这个0X23去指向谁啊?
25:08
指向这个对象吗?是吧,哎,好,继续看啊,继续看这个图要变了,各位啊,变了new了一个新的对象出来之后,地址给了这个这个new node0X45。0X45是这个对象地址啊,然后接下来是new node付给了last。妞弄的是这个节点,它的地址是0X450X45赋给了last,所以这块的值没了。嗯。给了他。给了他之后呢,这根线就没了,各位。
26:00
这根线没了,没了之后呢,他就指向谁,他就指向了他。明白吧,然后接下来这个程序继续往下,如果L等于空,这次L是等于空吗?L不等于空。L不是空,所以走这个吧,那走这个是l.next等于new node。L是谁,各位?是它0X23,它的X是不是这个值。它的ne等于new node new node是不是这个值?也就是说他是不是把这个值拿过来。放到了这个位置上。这个位置是不是指向了它。然后这个程序再往下走,是不是size加加。就行了,好大家看我加了两个元素之后啊,它就变成这样了,这个局部变量将来内存就释放了,你不用管它啊,就你不用看这这个这个将来这个方法执行结束,它就弹了,就走了,这根线和这根线都没了啊来我们把这个线。
27:14
擦一下各位啊,来这个没了啊,这个这个都没了。都没了吧?不行。这都没了啊。这块了啊,都没了。我直接给他切了得了。如果切了这一块,你就没了。这个没了各位啊。好,那么这根线也没了。
28:01
就这个意思啊,就这意思,嗯,这个这个这个地方这话呢,有点。行吧,就这个不太不太好画啊,不太好画,那这样的话,这个link list大家看看里边是不是有两个节点,有一个not first指向第一个,然后呢,Last是不是指向最后一个。然后第一个节点的下个节点是是不是保存下个节点内存地址,这个节点是不是上个。他上一个位置是不是保存上个阶段那个地址啊。对吧,它这个是这样的,大家理解吗?这个。最终搞来搞去搞到最后,实际上怎么着,各位跟我们的。刚才画的那个图是不是差不多。双向列表跟这个是不是差不多。对吧,这个节点保存的这个地址指向上一个,这个节点的下一个指向下一个吗。对不对。我们现在画的这个图就是这样的呀。那有同老师你再画一个。叫什么呀?C我不画了,太费劲啊,这个图画起来太费劲,各位,那将来肯定是在这里再加一个节点。
29:09
节点的关系没啥,就是源码有点圆码,你你这个源码怎么办?源码你一点一点看就就就好了。啊,一点一点看就好了,你不要着急,你一着急他就不行了啊,就不行了,那这个是我们的JDK13里边link给的一个情况,各位啊,就是first,其实这个永远指向。指向什么呀,指向第一个位置,这个应该指向什么,最后一个位置啊,就是将来。说白了啊,它就多了这么一个东西,比我们比比比我们这个图多了个啥,来保存一下。点右键啊。打开方式,编辑一下。来。Link list无非在这儿有一个什么呀?有一个。几点?对吧,叫什么叫。
30:00
里边保存一个什么内存地址吧,这个内存地址是0X55550X5555。明白吗?而这个0X55就指向谁啊?指向他了。明白吗?然后呢?还有一个啥。叫做。Last是不是啊,保存内存地址指向这个,这个是0X22,不能随便写啊,0X2222。好,他去指向谁呀?啊,其中。整个这个就是一个啥,就是一个link的例子,集合对象啊,整个这个就是一个集合对象,这里边儿有一个。First成员有一个last成员,你上来你就可以看到他源代码,你看first成员和last成员吗?
31:01
对不对,哎,First last,然后first呢,保它最初的时候是空啊,这是空,这里是空,那都是空的。当你见完第一个之后,它first指向这个,Last也指向它,然后加元素之后呢,First不变,往后呢,Last对吧?有新的出现了,有新的出现了,那就指向新的对象就行了。啊,它是这样一个一个一个过程啊,一个过程,大家有时间可以读一下源码啊,源代码其实呢,你通过读源代码就知道它是个双向链表了。它这个link list是个双向列表,空的空的对吧,你调的是这个I的方法,而这个I的方法调的link last link last方法往里边加的时候,你看它是怎么赋值的,你看附上值又丢一个附上值他又赋给他,他又给他就写这些干啥的,哎。只有这些代码,代码全部套起来,那将来才可以完成什么呀,我们这个元素的添加啊,元素的添加就是这样的。那么这个link list有初始化容量吗?各位link list的用法和list差不多啊?Link list有初始化容量吗?
32:05
有出装容量这一说吗?Link list集合有初始化。容量吗?答案是没有啊,没有。没有,最初这个链表中没有任何元素。啊,First和last引用都是那都是那啊。那不管,注意啊,我在这里写上,不管是link list还是A,以后写代码时不需要关心具体是哪个集合。啊,因为我们要面向接口编程,调用的方法都是接口中的方法,明白什么意思吗?List对吧,LIST2,你new一个a list也好,你一个我们的link list也好,对吧?哎,你面向接口编程啊,你爱的呀,是不是,哎123来。
33:14
2ID456456是不是,然后list2.i,然后呢,我们再几张,比如说789加上去之后呢,接下来我们在这里循环,是不是in I呢等于0I呢小于我们LIST2点什么size I干啥呀?加加,那么这个时候呢,我们输出就可以了,怎么输出呢?很简单,C out输出LIST2GET下边为I的这个元素,那么接下来我们去执行这个程序。编译并执行好123456789,那么现在如果说你把这行代码改了,你看看下面是不是根本就不需要做任何改动,只需要把这改成什么呀,叫link list就行了,再去运行程序,和刚才是一样的啊,是一样的,对,那只不过就是说你这里啊,这样写表示底层你用了数组。
34:06
啊,你这样写表示什么呀,底层你用了什么呀?啊,你用了双向链表,所以说我们第一天就跟大家说了,大家在Java语言中如果不够精通数据结构,能不能开发各位。就是你不精通数据结构,能写Java代码吗?能不能?嗯。行不行啊,这个答案是可以的啊,可以的。因为你只要拗就行了。明白什么意思吧,你只要new就可以了。啊,你new一个list,你new一个link list,你调接口的方法呀,你下面这个方法呀,对吧,以下这些方法,你面向的都是接口编程。对吧,你想想这个扩展能力强不强,扩展能力很强啊,你底层数据结构从数组变成了链表,你下面代码不用改。
35:06
看见了吗?这样的话你程序就很容易的完成扩展。就是你八个G的内存条想换成16个G,能不能换?可以这样换就行了。八个G的条子换成16个G的条子,你换呗,那其他地方不用动。不用动,接口还是那么大,这就叫面向接口编程。听明白了吗?哎,这个还是还是很经典的啊,还是很经典的接口,整个JDK的这个继承结构图这块设计的就很经典啊经典。
我来说两句