当前位置: 首页 > 后端技术 > Java

LinkedList添加元素源码分析

时间:2023-04-01 15:41:08 Java

jdk版本:1.8LinkedList有两个添加元素的方法:add(Ee)和add(intindex,Ee)。add(Ee)/***将指定元素附加到此列表的末尾。*在列表末尾添加指定元素*/publicbooleanadd(Ee){linkLast(e);返回真;}add(Ee)是直接在队尾添加元素。再看linkLast(Ee)方法,源码如下。voidlinkLast(Ee){//找到链表的最后一个节点,赋值给l,finalNodel=last;//创建一个节点,这个节点的前一个节点就是上面的最后一个节点finalNodenewNode=newNode<>(l,e,null);//将新节点赋给最后一个节点last=newNode;if(l==null)//如果没有最后一个节点,则说明添加的链表为空,将值赋值给第一个节点节点。第一个=新节点;else//有最后一个节点,将最后一个节点的next指针指向新创建的节点l.next=newNode;尺码++;模数++;}LinkedList会记录链表的最后一个节点last,首先创建一个新节点,new节点的pre为队列的最后一个节点last,新节点的next为null。如果last为空,则链表为空,新节点first为第一个节点。如果last不为空,说明链表不为空,last节点的next指针指向新节点。add(intindex,Ee)add(intindex,Ee)根据元素插入到指定位置,index表示链表的位置/***在这个链表的指定位置插入指定元素.*将指定的Element插入到列表的指定位置*/publicvoidadd(intindex,Eelement){//检查位置是否越界checkPositionIndex(index);//如果插入的下标等于链表的大小,则直接加入到队尾,if(index==size)linkLast(element);否则linkBefore(元素,节点(索引));}首先检查索引是否超过链表的大小,即索引是否会大于链表的大小。如果索引等于链表的大小,则添加一个元素就是在链表的末尾添加一个元素,与add(Ee)操作一致。如果在没有等待size的情况下调用linkBefore方法,首先使用node方法作为该方法的第二个参数。node方法的源码如下:Nodenode(intindex){//size>>1表示size右移,也就是size的一半//如果index小于超过一半大小,从第一个节点向后遍历if(index<(size>>1)){Nodex=first;for(inti=0;ix=last;for(inti=size-1;i>index;i--)x=x.prev;返回x;}}node方法通过链表的位置找到链表的元素。这里使用了size的右移操作,size>>1表示size/2。首先判断索引是在链表的前半部分还是后半部分,因为linkedList是双链表,可以向前向后遍历。如果前半部分从第一个节点向后遍历,后半部分从最后一个节点开始向前遍历,最多可以遍历一半大小,避免遍历整个链表。找到索引对应的元素后执行linkedBefore方法/***在非空节点succ之前插入元素e。*在succ节点之前插入元素*/voidlinkBefore(Ee,Nodesucc){//在succA节点之前finalNodepred=succ.prev;//创建新节点,新节点的pre为succ的pre节点,新节点的next为succ节点finalNodenewNode=newNode<>(pred,e,succ);//succ.pre指向新节点succ.prev=newNode;//如果succ之前的节点为空,则表示succ为首节点,新节点为首节点if(pred==null)first=newNode;else//succ前一个节点的next指向新节点pred.next=newNode;尺码++;模数++;}新建一个节点,节点pre为succ的pre,节点的next为succ。将succ.pre指向新节点。succ的pre为null,succ为第一个节点。将first分配给第一个节点。succ的pre不为空,则将succ的前一个节点的next指向新节点。总结链表。添加的方式只有两种,一种是在列表末尾添加(linkLast),一种是在列表中某个元素的前面添加(linkBefore)。LinkLast,先新建一个节点,节点pre指向最后一个节点,最后一个节点的next指向新节点。LinkBefore,首先根据索引下标获取元素的位置,创建一个新节点,新节点的pre为元素的pre,新节点的next为元素。元素的下一个pre指向新元素。为什么Linked使用双链表而不是单链表?判断索引是在链表的前半部分还是后半部分。如果是前半部分,则从前半部分遍历到中部分。如果是下半场,则从尾部遍历到中部。