内功心法 -- java.util.LinkedList (4)

时间:2021-10-04 04:20:47

写在前面的话:读书破万卷,编码如有神
--------------------------------------------------------------------
下文主要对java.util.LinkedList<E>的4个位置访问操作进行介绍,主要内容包括:

1、LinkedList常用的4个位置访问操作介绍

参考内容:

1、JDK源码(1.7)

--------------------------------------------------------------------

1、LinkedList常用的4个位置访问操作介绍                                 

(1)E get(int index)

功能: 返回此双端队列中index位置上的节点

示例代码:

 1 import java.util.LinkedList;
 2 
 3 public class LinkedListDemo {
 4     public static void main(String[] args) {
 5         /*********测试LinkedList的'E get(int index)'方法的使用**********/
 6         
 7         //创建一个LinkedList对象
 8         LinkedList<Student> linkedList = new LinkedList<Student>();
 9         
10         //创建一个Student对象,并将其添加到LinkedList对象中
11         Student stu1 = new Student(1,"zhangsan",20);
12         linkedList.add(stu1);
13         
14         //创建一个Student对象,并将其添加到LinkedList对象中
15         Student stu2 = new Student(2,"lisi",21);
16         linkedList.add(stu2);
17         
18         //创建一个Student对象,并将其添加到LinkedList对象中
19         Student stu3 = new Student(3,"wangwu",22);
20         linkedList.add(stu3);
21         System.out.println("linkedList:" + linkedList);
22         
23         System.out.println("linkedList.get(2):" + linkedList.get(2));
24         System.out.println("linkedList:" + linkedList);
25         
26         //此方法将抛出异常
27         System.out.println("linkedList.get(5):" + linkedList.get(5));
28     }
29 }
30 
31 运行结果:
32 linkedList:[Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22]]
33 linkedList.get(2):Student [stuId=3, stuName=wangwu, stuAge=22]
34 linkedList:[Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22]]
35 Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 5, Size: 3
36     at java.util.LinkedList.checkElementIndex(LinkedList.java:553)
37     at java.util.LinkedList.get(LinkedList.java:474)
38     at LinkedListDemo.main(LinkedListDemo.java:27)

源代码如下:

 1     /*
 2        返回此双端队列中index位置上的节点
 3     */
 4     public E get(int index) {
 5         //检查index参数是否合法,调用内部方法checkElementIndex
 6         checkElementIndex(index);
 7 
 8         //返回双端队列中index位置上的节点
 9         return node(index).item;
10     }
11 
12     /*
13         检查index参数是否合法
14     */
15     private void checkElementIndex(int index) {
16         //如果不合法,则抛出异常
17         if (!isElementIndex(index))
18             throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
19     }
20 
21     /*
22         检查参数index是合法
23     */
24     private boolean isElementIndex(int index) {
25         return index >= 0 && index < size;
26     }
27 
28     /*
29          返回双端队列index位置上的节点
30     */
31     Node<E> node(int index) {
32         // assert isElementIndex(index);
33 
34         if (index < (size >> 1)) {
35             //如果要求返回的节点位置index,在双端队列的前一半,则从头往尾找
36             Node<E> x = first;
37             for (int i = 0; i < index; i++)
38                 x = x.next;
39             return x;
40         } else {
41             //如果要求返回的节点位置index,在双端队列的后一半,则从尾往头找
42             Node<E> x = last;
43             for (int i = size - 1; i > index; i--)
44                 x = x.prev;
45             return x;
46         }
47     }

(2)E set(int index, E element)

功能: 将此双端队列中index位置上的节点替换为element节点,并返回被替换的节点

示例代码:

 1 import java.util.LinkedList;
 2 
 3 public class LinkedListDemo {
 4     public static void main(String[] args) {
 5         /*********测试LinkedList的'E set(int index, E element)'方法的使用**********/
 6         
 7         //创建一个LinkedList对象
 8         LinkedList<Student> linkedList = new LinkedList<Student>();
 9         
10         //创建一个Student对象,并将其添加到LinkedList对象中
11         Student stu1 = new Student(1,"zhangsan",20);
12         linkedList.add(stu1);
13         
14         //创建一个Student对象,并将其添加到LinkedList对象中
15         Student stu2 = new Student(2,"lisi",21);
16         linkedList.add(stu2);
17         
18         //创建一个Student对象,并将其添加到LinkedList对象中
19         Student stu3 = new Student(3,"wangwu",22);
20         linkedList.add(stu3);
21         System.out.println("linkedList:" + linkedList);
22         
23         Student stu4 = new Student(4,"xiaohong",22);
24         System.out.println("linkedList.set(1,stu4):" + linkedList.set(1,stu4));
25         System.out.println("linkedList:" + linkedList);
26         
27         //此方法将抛出异常
28         System.out.println("linkedList.set(7,stu4):" + linkedList.set(7,stu4));
29     }
30 }
31 
32 运行结果:
33 linkedList:[Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22]]
34 linkedList.set(1,stu4):Student [stuId=2, stuName=lisi, stuAge=21]
35 linkedList:[Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=4, stuName=xiaohong, stuAge=22], Student [stuId=3, stuName=wangwu, stuAge=22]]
36 Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 7, Size: 3
37     at java.util.LinkedList.checkElementIndex(LinkedList.java:553)
38     at java.util.LinkedList.set(LinkedList.java:488)
39     at LinkedListDemo.main(LinkedListDemo.java:28)

源代码如下:

 1    /*
 2         将此双端队列中index位置上的节点替换为element节点,并返回被替换的节点
 3    */ 
 4    public E set(int index, E element) {
 5         //检查index参数是否合法
 6         checkElementIndex(index);
 7         //查找双端队列中index位置上的节点
 8         Node<E> x = node(index);
 9         //记录要被替换的节点
10         E oldVal = x.item;
11         //设置双端队列中index位置上的节点的值为element
12         x.item = element;
13         //返回被替换的老节点
14         return oldVal;
15     }

(3)void add(int index, E element)

功能: 将元素element添加到双端队列的index位置上

示例代码:

 1 import java.util.LinkedList;
 2 
 3 public class LinkedListDemo {
 4     public static void main(String[] args) {
 5         /*********测试LinkedList的'void add(int index, E element)'方法的使用**********/
 6         
 7         //创建一个LinkedList对象
 8         LinkedList<Student> linkedList = new LinkedList<Student>();
 9         
10         //创建一个Student对象,并将其添加到LinkedList对象中
11         Student stu1 = new Student(1,"zhangsan",20);
12         linkedList.add(stu1);
13         
14         //创建一个Student对象,并将其添加到LinkedList对象中
15         Student stu2 = new Student(2,"lisi",21);
16         linkedList.add(stu2);
17         
18         //创建一个Student对象,并将其添加到LinkedList对象中
19         Student stu3 = new Student(3,"wangwu",22);
20         linkedList.add(stu3);
21         System.out.println("linkedList:" + linkedList);
22         
23         Student stu4 = new Student(4,"xiaohong",22);
24         linkedList.add(1,stu4);
25         System.out.println("linkedList:" + linkedList);
26         
27         //此方法将抛出异常
28         linkedList.add(7,stu4);
29     }
30 }
31 
32 运行结果:
33 linkedList:[Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22]]
34 linkedList:[Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=4, stuName=xiaohong, stuAge=22], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22]]
35 Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 7, Size: 4
36     at java.util.LinkedList.checkPositionIndex(LinkedList.java:558)
37     at java.util.LinkedList.add(LinkedList.java:505)
38     at LinkedListDemo.main(LinkedListDemo.java:28)

源代码如下:

 1     /*
 2       功能: 将元素element添加到双端队列的index位置
 3     */
 4     public void add(int index, E element) {
 5 
 6         //检查参数index是否合法
 7         checkPositionIndex(index);
 8 
 9         
10         if (index == size){
11             //添加到双端队列的尾部
12             linkLast(element);
13         }
14         else{
15             //添加在双端队列的中间
16             linkBefore(element, node(index));
17         }
18     }    

(4)E remove(int index)

功能: 将此双端队列的index位置上的元素删除

示例代码:

 1 import java.util.LinkedList;
 2 
 3 public class LinkedListDemo {
 4     public static void main(String[] args) {
 5         /*********测试LinkedList的'E remove(int index)'方法的使用**********/
 6         
 7         //创建一个LinkedList对象
 8         LinkedList<Student> linkedList = new LinkedList<Student>();
 9         
10         //创建一个Student对象,并将其添加到LinkedList对象中
11         Student stu1 = new Student(1,"zhangsan",20);
12         linkedList.add(stu1);
13         
14         //创建一个Student对象,并将其添加到LinkedList对象中
15         Student stu2 = new Student(2,"lisi",21);
16         linkedList.add(stu2);
17         
18         //创建一个Student对象,并将其添加到LinkedList对象中
19         Student stu3 = new Student(3,"wangwu",22);
20         linkedList.add(stu3);
21         System.out.println("linkedList:" + linkedList);
22         
23         System.out.println("linkedList.remove(2):" + linkedList.remove(2));
24         System.out.println("linkedList:" + linkedList);
25         
26         //此方法将会抛出异常
27         linkedList.remove(8);
28     }
29 }
30 
31 运行结果:
32 linkedList:[Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22]]Exception in thread "main" 
33 linkedList.remove(2):Student [stuId=3, stuName=wangwu, stuAge=22]
34 linkedList:[Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21]]
35 java.lang.IndexOutOfBoundsException: Index: 8, Size: 2
36     at java.util.LinkedList.checkElementIndex(LinkedList.java:553)
37     at java.util.LinkedList.remove(LinkedList.java:523)
38     at LinkedListDemo.main(LinkedListDemo.java:27)

源代码如下:

 1     /*
 2       将此双端队列的index位置上的元素删除
 3    */
 4     public E remove(int index) {
 5         //检查参数index是否合法
 6         checkElementIndex(index);
 7         //删除节点
 8         return unlink(node(index));
 9     }
10 
11     //检查参数index是合法
12     private void checkElementIndex(int index) {
13         //调用内部方法isElementIndex检查参数index是合法,不合法则抛出异常
14         if (!isElementIndex(index))
15             throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
16     }
17 
18     //检查参数index是否合法
19     private boolean isElementIndex(int index) {
20         return index >= 0 && index < size;
21     }
22 
23     //返回此双端队列index位置上的节点元素
24     Node<E> node(int index) {
25         // assert isElementIndex(index);
26 
27         
28         if (index < (size >> 1)) {
29             //如果要求返回的节点位置index,在双端队列的前一半,则从头往尾找
30             Node<E> x = first;
31             for (int i = 0; i < index; i++)
32                 x = x.next;
33             return x;
34         } else {
35             //如果要求返回的节点位置index,在双端队列的后一半,则从尾往头找
36             Node<E> x = last;
37             for (int i = size - 1; i > index; i--)
38                 x = x.prev;
39             return x;
40         }
41     }
42     
43      /*
44         删除双端队列中 节点x
45     */
46     E unlink(Node<E> x) {
47         // assert x != null;
48         //记录x节点的值
49         final E element = x.item;
50         //记录x节点的下一个节点
51         final Node<E> next = x.next;
52         //记录x节点的上一个节点
53         final Node<E> prev = x.prev;
54         
55         if (prev == null) {
56             //如果x节点没有上一个节点,则赋值双端队列对象的first属性为next
57             first = next;
58         } else {
59             //如果x节点有上一个节点,则赋值x节点的上一个节点的next属性为next
60             prev.next = next;
61             x.prev = null;
62         }
63 
64         if (next == null) {
65             //如果x节点没有下一个节点,则赋值双端队列对象的last属性为prev
66             last = prev;
67         } else {
68             //如果x节点有下一个节点,则赋值x节点的下一个节点的prev属性为prev
69             next.prev = prev;
70             x.next = null;
71         }
72         
73         //设置被删除节点的值为null,方便GC
74         x.item = null;
75         //双端队列中元素个数减1
76         size--;
77         //fast-fail机制标识加1
78         modCount++;
79         return element;
80     }

--------------------------------------------------------------------

java.util.LinkedList<E>系列文章                                            

java.util.LinkedList<E>(1)  java.util.LinkedList<E>(2)  java.util.LinkedList<E>(3)

java.util.LinkedList<E>(4)  java.util.LinkedList<E>(5)  java.util.LinkedList<E>(6)

java.util.LinkedList<E>(7)  java.util.LinkedList<E>(8)  

--------------------------------------------------------------------

相关知识                                                                             

java.util.Collection<E>   java.util.AbstractCollection<E>   java.util.List<E>

java.util.AbstractList<E>   java.util.Iterator<E>   java.util.ListIterator<E>

Java中的标记接口   迭代器模式   Java中的深拷贝和浅拷贝  java.util.Arrays

java.util.Queue<E>  java.util.Deque<E>