内功心法 -- java.util.LinkedList<E> (7)
写在前面的话:读书破万卷,编码如有神
--------------------------------------------------------------------
下文主要对java.util.LinkedList<E>的10个双端队列操作进行介绍,主要内容包括:
1、LinkedList常用的10个双端队列操作介绍
参考内容:
1、JDK源码(1.7)
--------------------------------------------------------------------
1、LinkedList常用的10个双端队列操作介绍
(1)boolean offerFirst(E e)
功能: 将指定的元素e插入此双端队列的开头
示例代码:
1 import java.util.LinkedList; 2 3 public class LinkedListDemo { 4 public static void main(String[] args) { 5 /*********测试LinkedList的'boolean offerFirst(E e)'方法的使用**********/ 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 Student stu4 = new Student(4,"oopp",22); 25 System.out.println("linkedList.offerFirst(stu4):" + linkedList.offerFirst(stu4)); 26 System.out.println("linkedList:" + linkedList); 27 } 28 } 29 30 运行结果: 31 linkedList:[Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22]] 32 linkedList.offerFirst(stu4):true 33 linkedList:[Student [stuId=4, stuName=oopp, stuAge=22], Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22]]
源代码如下:
1 /* 2 将指定的元素e插入到此双端队列的开头 3 */ 4 public boolean offerFirst(E e) { 5 //调用内部方法addFirst实现 6 addFirst(e); 7 return true; 8 } 9 10 /* 11 将指定的元素e插入到此双端队列的开头 12 */ 13 public void addFirst(E e) { 14 //调用内部方法linkFirst实现 15 linkFirst(e); 16 } 17 18 /* 19 将指定的元素e插入到此双端队列的开头 20 */ 21 private void linkFirst(E e) { 22 //引用f指向此双端队列的开头 23 final Node<E> f = first; 24 //新建一个Node节点 25 final Node<E> newNode = new Node<>(null, e, f); 26 //此双端队列对象的first属性指向刚新建的Node节点 27 first = newNode; 28 29 //如果此双端队列为空, 30 //则双端队列对象的last属性也指向刚新建的Node节点 31 //否则原双端队列的头节点的prev属性指向刚新建的Node节点 32 if (f == null) 33 last = newNode; 34 else 35 f.prev = newNode; 36 //双端队列中元素个数加1 37 size++; 38 //fast-fail机制加1 39 modCount++; 40 }
(2)boolean offerLast(E e)
功能: 将指定的元素e插入此双端队列的尾部
示例代码:
1 import java.util.LinkedList; 2 3 public class LinkedListDemo { 4 public static void main(String[] args) { 5 /*********测试LinkedList的'boolean offerLast(E e) '方法的使用**********/ 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 Student stu4 = new Student(4,"oopp",22); 25 System.out.println("linkedList.offerLast(stu4):" + linkedList.offerLast(stu4)); 26 System.out.println("linkedList:" + linkedList); 27 } 28 } 29 30 运行结果: 31 linkedList:[Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22]] 32 linkedList.offerLast(stu4):true 33 linkedList:[Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22], Student [stuId=4, stuName=oopp, stuAge=22]]
源代码如下:
1 /* 2 将指定的元素e插入到此双端队列的尾部 3 */ 4 public boolean offerLast(E e) { 5 //调用方法addLast实现 6 addLast(e); 7 return true; 8 } 9 10 /* 11 将指定的元素e插入到此双端队列的尾部 12 */ 13 public void addLast(E e) { 14 //调用方法linkLast实现 15 linkLast(e); 16 } 17 18 /* 19 将指定的元素e插入到此双端队列的尾部 20 */ 21 void linkLast(E e) { 22 //将引用l指向此双端队列的尾部 23 final Node<E> l = last; 24 //新建一个Node节点 25 final Node<E> newNode = new Node<>(l, e, null); 26 //此双端队列对象的last属性指向刚新建的Node节点 27 last = newNode; 28 29 //如果此双端队列为空 30 //则双端队列对象的first属性指向刚新建的Node节点 31 //否则原双端队列尾部对象的next属性指向刚新建的Node节点 32 if (l == null) 33 first = newNode; 34 else 35 l.next = newNode; 36 //双端队列中节点元素个数加1 37 size++; 38 //fast-fail机制加1 39 modCount++; 40 }
(3)E peekFirst()
功能: 获取,但不移除此双端队列的第一个元素(如果此双端队列为空,则返回 null)
示例代码:
1 import java.util.LinkedList; 2 3 public class LinkedListDemo { 4 public static void main(String[] args) { 5 /*********测试LinkedList的'E peekFirst() '方法的使用**********/ 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.peekFirst():" + linkedList.peekFirst()); 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.peekFirst():Student [stuId=1, stuName=zhangsan, stuAge=20] 31 linkedList:[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 E peekFirst() { 5 final Node<E> f = first; 6 return (f == null) ? null : f.item; 7 }
(4)E peekLast()
功能: 获取,但不移除此双端队列的最后一个元素(如果此双端队列为空,则返回 null)
示例代码:
1 import java.util.LinkedList; 2 3 public class LinkedListDemo { 4 public static void main(String[] args) { 5 /*********测试LinkedList的'E peekLast()'方法的使用**********/ 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.peekLast():" + linkedList.peekLast()); 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.peekLast():Student [stuId=3, stuName=wangwu, stuAge=22] 31 linkedList:[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 E peekLast() { 5 //引用l指向此双端队列的最后一个元素 6 final Node<E> l = last; 7 //返回双端队列最后一个元素 8 return (l == null) ? null : l.item; 9 }
(5)E pollFirst()
功能: 获取并移除此双端队列的第一个元素(如果此双端队列为空,则返回 null)
示例代码:
1 import java.util.LinkedList; 2 3 public class LinkedListDemo { 4 public static void main(String[] args) { 5 /*********测试LinkedList的'E pollFirst()'方法的使用**********/ 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.pollFirst():" + linkedList.pollFirst()); 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.pollFirst():Student [stuId=1, stuName=zhangsan, stuAge=20] 31 linkedList:[Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22]]
源代码如下:
1 /* 2 获取并移除此双端队列的第一个元素(如果双端队列为空,则返回null) 3 */ 4 public E pollFirst() { 5 //引用f指向此双端队列的第一个节点元素 6 final Node<E> f = first; 7 //返回并移除双端队列的第一个元素 8 return (f == null) ? null : unlinkFirst(f); 9 } 10 11 /* 12 获取并移除此双端队列的第一个元素 13 */ 14 private E unlinkFirst(Node<E> f) { 15 // assert f == first && f != null; 16 //记录双端队列的第一个节点的值 17 final E element = f.item; 18 //记录双端队列的第二个节点 19 final Node<E> next = f.next; 20 21 //将双端队列的头节点的item、next都设置为null,帮助GC回收 22 f.item = null; 23 f.next = null; // help GC 24 25 //此双端队列对象的first属性指向第二个节点 26 //如果第二个节点尾null,则设置双端队列对象的last属性为null 27 //否则设置第二个节点的prev属性为null 28 first = next; 29 if (next == null) 30 last = null; 31 else 32 next.prev = null; 33 //此双端队列中元素个数减1 34 size--; 35 //fast-fail机制加1 36 modCount++; 37 //返回被删除的节点 38 return element; 39 }
(6)E pollLast()
功能: 获取并移除此双端队列的最后一个元素(如果此双端队列为空,则返回 null)
示例代码:
1 import java.util.LinkedList; 2 3 public class LinkedListDemo { 4 public static void main(String[] args) { 5 /*********测试LinkedList的'E pollLast()'方法的使用**********/ 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.pollLast():" + linkedList.pollLast()); 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.pollLast():Student [stuId=3, stuName=wangwu, stuAge=22] 31 linkedList:[Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21]]
源代码如下:
1 /* 2 获取并移除此双端队列的最后一个元素(如果此双端队列为空,则返回null) 3 */ 4 public E pollLast() { 5 //引用l指向双端独立的最后一个节点 6 final Node<E> l = last; 7 //返回并移除此双端队列的最后一个节点 8 return (l == null) ? null : unlinkLast(l); 9 } 10 11 /* 12 返回并移除此双端队列的最后一个节点 13 */ 14 private E unlinkLast(Node<E> l) { 15 // assert l == last && l != null; 16 //记录双端队列的最后一个节点的值 17 final E element = l.item; 18 //记录双端队列的倒数第二个节点 19 final Node<E> prev = l.prev; 20 21 //设置双端队列最后一个节点的item、prev为null,帮助GC回收 22 l.item = null; 23 l.prev = null; // help GC 24 25 //双端队列对象的last属性指向双端队列的倒数第二个节点 26 last = prev; 27 //如果双端队列的倒数第二个节点为null 28 //则双端队列的first属性为null 29 //否则双端队列的倒数第二个节点的next属性为null 30 if (prev == null) 31 first = null; 32 else 33 prev.next = null; 34 //双端队列中的元素个数减1 35 size--; 36 //fast-fail机制加1 37 modCount++; 38 //返回并移除的节点 39 return element; 40 }
(7)void push(E e)
功能: 将一个元素推入此双端队列所表示的堆栈;如果成功,则返回 true
示例代码:
1 import java.util.LinkedList; 2 3 public class LinkedListDemo { 4 public static void main(String[] args) { 5 /*********测试LinkedList的'void push(E e)'方法的使用**********/ 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.push(stu4); 25 System.out.println("linkedList:" + linkedList); 26 } 27 } 28 29 运行结果: 30 linkedList:[Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22]] 31 linkedList:[Student [stuId=4, stuName=xiaohong, stuAge=22], Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22]]
源代码如下:
1 /* 2 将元素e添加到此双端队列所表示的堆栈中 3 */ 4 public void push(E e) { 5 //调用addFirst方法实现 6 addFirst(e); 7 }
(8)E pop()
功能: 从此双端队列所表示的堆栈中弹出一个元素
示例代码:
1 import java.util.LinkedList; 2 3 public class LinkedListDemo { 4 public static void main(String[] args) { 5 /*********测试LinkedList的'E pop()'方法的使用**********/ 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.pop():" + linkedList.pop()); 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.pop():Student [stuId=1, stuName=zhangsan, stuAge=20] 31 linkedList:[Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22]]
源代码如下:
/* 从此双端队列所表示的堆栈中弹出一个元素 */ public E pop() { //调用removeFirst方法实现 return removeFirst(); }
(9)boolean removeFirstOccurrence(Object o)
功能: 从此双端队列移除第一次出现的指定元素
示例代码:
import java.util.LinkedList; public class LinkedListDemo { public static void main(String[] args) { /*********测试LinkedList的'boolean removeFirstOccurrence(Object o)'方法的使用**********/ //创建一个LinkedList对象 LinkedList<Student> linkedList = new LinkedList<Student>(); //创建一个Student对象,并将其添加到LinkedList对象中 Student stu1 = new Student(1,"zhangsan",20); linkedList.add(stu1); //创建一个Student对象,并将其添加到LinkedList对象中 Student stu2 = new Student(2,"lisi",21); linkedList.add(stu2); //创建一个Student对象,并将其添加到LinkedList对象中 Student stu3 = new Student(3,"wangwu",22); linkedList.add(stu3); System.out.println("linkedList:" + linkedList); System.out.println("linkedList.removeFirstOccurrence(stu2):" + linkedList.removeFirstOccurrence(stu2)); System.out.println("linkedList:" + linkedList); } } 运行结果: linkedList:[Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22]] linkedList.removeFirstOccurrence(stu2):true linkedList:[Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=3, stuName=wangwu, stuAge=22]]
源代码如下:
1 /* 2 从此双端队列移除第一次出现的指定元素o 3 */ 4 public boolean removeFirstOccurrence(Object o) { 5 //调用方法remove实现 6 return remove(o); 7 }
(10)boolean removeLastOccurrence(Object o)
功能: 从此双端队列移除最后一次出现的指定元素
示例代码:
1 import java.util.LinkedList; 2 3 public class LinkedListDemo { 4 public static void main(String[] args) { 5 /*********测试LinkedList的'boolean removeLastOccurrence(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 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 linkedList.add(stu2); 22 linkedList.add(stu3); 23 System.out.println("linkedList:" + linkedList); 24 25 System.out.println("linkedList.removeLastOccurrence(stu2):" + linkedList.removeLastOccurrence(stu2)); 26 System.out.println("linkedList:" + linkedList); 27 } 28 } 29 30 运行结果: 31 linkedList:[Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22]] 32 linkedList.removeLastOccurrence(stu2):true 33 linkedList:[Student [stuId=1, stuName=zhangsan, stuAge=20], Student [stuId=2, stuName=lisi, stuAge=21], Student [stuId=3, stuName=wangwu, stuAge=22], Student [stuId=3, stuName=wangwu, stuAge=22]]
源代码如下:
1 /* 2 从此双端队列移除最后一次出现的指定元素o 3 */ 4 public boolean removeLastOccurrence(Object o) { 5 if (o == null) { 6 //当元素o为null时 7 //循环逆序遍历此双端队列,查询值为null的节点 8 for (Node<E> x = last; x != null; x = x.prev) { 9 if (x.item == null) { 10 //移除此节点 11 unlink(x); 12 return true; 13 } 14 } 15 } else { 16 //当元素o不为null时 17 //循环逆序遍历此双端队列,查询值等于节点o的值的节点 18 for (Node<E> x = last; x != null; x = x.prev) { 19 if (o.equals(x.item)) { 20 //移除此节点 21 unlink(x); 22 return true; 23 } 24 } 25 } 26 return false; 27 }
--------------------------------------------------------------------
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>