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

时间:2022-11-08 17:36:28

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

1、LinkedList常用5个修改操作介绍

参考内容:

1、JDK源码(1.7)

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

1、LinkedList常用5个修改操作介绍                                          

(1)boolean add(E e)

功能: 将指定元素插入此双端队列的尾部

示例代码:

 1 import java.util.LinkedList;
 2 
 3 public class LinkedListDemo {
 4     public static void main(String[] args) {
 5         /*********测试LinkedList的'boolean add()'方法的使用**********/
 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         System.out.println(linkedList);
14         
15         //创建一个Student对象,并将其添加到LinkedList对象中
16         Student stu2 = new Student(2,"lisi",21);
17         linkedList.add(stu2);
18         System.out.println(linkedList);
19         
20         //创建一个Student对象,并将其添加到LinkedList对象中
21         Student stu3 = new Student(3,"wangwu",22);
22         linkedList.add(stu3);
23         System.out.println(linkedList);
24     }
25 }
26 
27 运行结果:
28 [Student [stuId=1, stuName=zhangsan, stuAge=20]]
29 [Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21]]
30 [Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22]]

源代码如下:

 1     /*
 2      将指定元素插入此双端队列的尾部
 3    */
 4     public boolean add(E e) {
 5         //调用内部方法
 6         linkLast(e);
 7         return true;
 8     }
 9 
10     /*
11        将元素e链接到此双端队列的尾部 
12     */
13     void linkLast(E e) {
14         //引用l指向此双端队列对象的尾节点
15         final Node<E> l = last;
16         //新建一个Node节点
17         final Node<E> newNode = new Node<>(l, e, null);
18         //设置此双端队列对象的last属性指向刚新建的Node节点
19         last = newNode;
20         //如果此双端队列中没有节点存在,则设置此双端队列对象的first属性也指向刚新建的Node节点,否则原来的尾节点的next属性指向刚新建的Node节点
21         if (l == null)
22             first = newNode;
23         else
24             l.next = newNode;
25         //双端队列中节点个数加1
26         size++;
27         //fast-fail机制加1
28         modCount++;
29     }

(2)boolean remove(Object o)

功能: 移除此双端队列中的元素o

示例代码:

 1 import java.util.LinkedList;
 2 
 3 public class LinkedListDemo {
 4     public static void main(String[] args) {
 5         /*********测试LinkedList的'boolean remove(Object o)'方法的使用**********/
 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         System.out.println(linkedList);
14         
15         //创建一个Student对象,并将其添加到LinkedList对象中
16         Student stu2 = new Student(2,"lisi",21);
17         linkedList.add(stu2);
18         System.out.println(linkedList);
19         
20         //创建一个Student对象,并将其添加到LinkedList对象中
21         Student stu3 = new Student(3,"wangwu",22);
22         linkedList.add(stu3);
23         System.out.println(linkedList);
24         
25         
26         System.out.println("linkedList.remove(stu2) : "+linkedList.remove(stu2));
27         System.out.println(linkedList);
28         
29         System.out.println("linkedList.remove(null) : "+linkedList.remove(null));
30         System.out.println(linkedList);
31     }
32 }
33 
34 运行结果:
35 [Student [stuId=1, stuName=zhangsan, stuAge=20]]
36 [Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21]]
37 [Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22]]
38 linkedList.remove(stu2) : true
39 [Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=3, stuName=wangwu, stuAge=22]]
40 linkedList.remove(null) : false
41 [Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=3, stuName=wangwu, stuAge=22]]

源代码如下:

 1     /*
 2        从双端队列中移除对象o
 3     */
 4     public boolean remove(Object o) {
 5         if (o == null) {
 6             //对象o为null时
 7             //利用for循环双端队列,查询值为null的节点,
 8             for (Node<E> x = first; x != null; x = x.next) {
 9                 //找到值为null的节点,调用内部方法unlink()进行删除
10                 if (x.item == null) {
11                     unlink(x);
12                     return true;
13                 }
14             }
15         } else {
16             //对象o不为null时
17             //利用for循环双端队列,查询值与o对象的值相等的节点
18             for (Node<E> x = first; x != null; x = x.next) {
19                 //找到值与o对象的值相等的节点,调用内部方法unlink()进行删除
20                 if (o.equals(x.item)) {
21                     unlink(x);
22                     return true;
23                 }
24             }
25         }
26         return false;
27     }
28 
29 
30     /*
31         删除双端队列中 节点x
32     */
33     E unlink(Node<E> x) {
34         // assert x != null;
35         //记录x节点的值
36         final E element = x.item;
37         //记录x节点的下一个节点
38         final Node<E> next = x.next;
39         //记录x节点的上一个节点
40         final Node<E> prev = x.prev;
41         
42         if (prev == null) {
43             //如果x节点没有上一个节点,则赋值双端队列对象的first属性为next
44             first = next;
45         } else {
46             //如果x节点有上一个节点,则赋值x节点的上一个节点的next属性为next
47             prev.next = next;
48             x.prev = null;
49         }
50 
51         if (next == null) {
52             //如果x节点没有下一个节点,则赋值双端队列对象的last属性为prev
53             last = prev;
54         } else {
55             //如果x节点有下一个节点,则赋值x节点的下一个节点的prev属性为prev
56             next.prev = prev;
57             x.next = null;
58         }
59         
60         //设置被删除节点的值为null,方便GC
61         x.item = null;
62         //双端队列中元素个数减1
63         size--;
64         //fast-fail机制标识加1
65         modCount++;
66         return element;
67     }

(3)boolean addAll(Collection<? extends E> c)

功能:  将子集合c中的全部插入到此双端队列的尾部

示例代码:

源代码如下:

1     public boolean addAll(Collection<? extends E> c) {
2         //调用方法addAll(size, c)
3         return addAll(size, c);
4     }

(4)boolean addAll(int index, Collection<? extends E> c)

功能: 将子集合c中的全部插入到此双端队列的index开始位置

示例代码:

 1 import java.util.LinkedList;
 2 
 3 public class LinkedListDemo {
 4     public static void main(String[] args) {
 5         /*********测试LinkedList的'boolean addAll(int index, Collection<? extends E> c)'方法的使用**********/
 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         
24         //创建一个LinkedList对象
25         LinkedList<Student> linkedList1 = new LinkedList<Student>();
26         
27         //创建一个Student对象,并将其添加到LinkedList对象中
28         Student stu10 = new Student(10,"zhangsan1",20);
29         linkedList1.add(stu10);
30         
31         //创建一个Student对象,并将其添加到LinkedList对象中
32         Student stu20 = new Student(20,"lisi2",21);
33         linkedList1.add(stu20);
34         
35         //创建一个Student对象,并将其添加到LinkedList对象中
36         Student stu30 = new Student(30,"wangwu3",22);
37         linkedList1.add(stu30);
38         System.out.println("linkedList1:" + linkedList1);
39         
40         System.out.println("linkedList1.addAll(2, linkedList) =" + linkedList1.addAll(2, linkedList));
41         System.out.println("linkedList1:" + linkedList1);
42     }
43 }
44 
45 运行结果:
46 linkedList:[Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22]]
47 linkedList1:[Student [stuId=10, stuName=zhangsan1, stuAge=20], Student [stuId=20, stuName=lisi2, stuAge=21], Student [stuId=30, stuName=wangwu3, stuAge=22]]
48 linkedList1.addAll(2, linkedList) =true
49 linkedList1:[Student [stuId=10, stuName=zhangsan1, stuAge=20], Student [stuId=20, stuName=lisi2, stuAge=21], Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22], Student [stuId=30, stuName=wangwu3, stuAge=22]]

源代码如下:

 1     /*
 2        将子集合c中的全部元素插入到此双端队列的index开始的位置
 3    */
 4     public boolean addAll(int index, Collection<? extends E> c) {
 5         //检查插入位置index是否合法
 6         checkPositionIndex(index);
 7         
 8         //将待插入的子集合转换成Object数组
 9         Object[] a = c.toArray();
10         //记录待插入子集合中元素的个数
11         int numNew = a.length; 
12         //如果待插入子集合中元素的个数为0,则直接返回
13         if (numNew == 0)
14             return false;
15         
16         //引用pred指向待插入位置的前一个节点
17         //引用succ指向待插入位置的节点
18         Node<E> pred, succ;
19         if (index == size) {
20             //将子集合插入在双端队列的尾部
21             succ = null;
22             pred = last;
23         } else {
24             //不是将子集合插入在双端队列的尾部
25             //引用succ记录双端队列中index位置上的节点
26             succ = node(index);
27             //引用pred记录双端队列中index位置上的前节点
28             pred = succ.prev;
29         }
30 
31         //利用for循环依次将子集合中的元素插入到此双端队列中
32         for (Object o : a) {
33             //新建一个Node节点
34             @SuppressWarnings("unchecked") E e = (E) o;
35             Node<E> newNode = new Node<>(pred, e, null);
36             if (pred == null)
37                 first = newNode;
38             else
39                 pred.next = newNode;
40             pred = newNode;
41         }
42 
43         //重新链接节点
44         if (succ == null) {
45             last = pred;
46         } else {
47             pred.next = succ;
48             succ.prev = pred;
49         }
50         
51         //双端队列中元素个数加上numNew
52         size += numNew;
53         //fast-fail机制加1
54         modCount++;
55         return true;
56     }

(5)void clear()

功能: 将此双端队列中的元素节点全部清空

示例代码:

 1 import java.util.LinkedList;
 2 
 3 public class LinkedListDemo {
 4     public static void main(String[] args) {
 5         /*********测试LinkedList的'void clear()'方法的使用**********/
 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         linkedList.clear();
24         System.out.println("linkedList:" + linkedList);
25     }
26 }
27 
28 运行结果:
29 linkedList:[Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22]]
30 linkedList:[]

源代码如下:

 1     /*
 2        将此双端队列中的元素节点全部清空
 3     */
 4     public void clear() {
 5         //利用for循环从双端队列的头到尾,依次清空
 6         for (Node<E> x = first; x != null; ) {
 7             Node<E> next = x.next;
 8             x.item = null;
 9             x.next = null;
10             x.prev = null;
11             x = next;
12         }
13         //将双端队列对象的first、last属性设置为null
14         first = last = null;
15         //将双端队列对象的size设置为0
16         size = 0;
17         //fast-fail机制加1
18         modCount++;
19     }

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

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>