java集合类(六)About Queue
终于来到了java集合类的尾声,太兴奋了,不是因为可以休息一阵了,而是因为又到了开启新知识的时刻,大家一起加油打气!!Come on...Fighting!
- About “interface Queue<E>”
- All Superinterfaces:Collection<E>, Iterable<E>
- All Known Subinterfaces:BlockingDeque<E>, BlockingQueue<E>, Deque<E>, TransferQueue<E>
- All Known Implementing Classes:AbstractQueue, ArrayBlockingQueue, ArrayDeque, ConcurrentLinkedDeque, ConcurrentLinkedQueue, DelayQueue, LinkedBlockingDeque, LinkedBlockingQueue, LinkedList, LinkedTransferQueue, PriorityBlockingQueue, PriorityQueue, SynchronousQueue
- 先简要说明下队列:
- 之前,在“java集合类(三)About Iterator & Vector(Stack)”中讲到堆(heap)与栈(stack)的区别,现在讨论栈Stack与队列Queue的区别:
- 1)队列:FIFO先进先出,栈LIFO后进先出
- 2)队列:从队尾进对头出,栈:栈顶进栈顶出
- 3)遍历的速度不同:栈只能从栈顶取数,要得到最先入栈的元素,必须遍历这个栈,而且还需要开辟临时空间;队列则不同,它基于指针进行遍历,可以从对头或者队尾开始(不能同时),无需临时空间,遍历过程不影响数据结构,速度要快得多
- Queue的实现:在学习LinkedList的时候,我们已知道LinkedList实现了Queue接口,所以今天的Queue也可以用LinkedList实现,并且LinkedList还实现了Stack(java集合类(三)About Iterator & Vector(Stack)提到),所以我们也可以设想能不能用Stack实现Queue?答案是肯定的, 不过要用两个Stack才能实现! 现在来看一个Queue的基础例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import java.util.LinkedList; import java.util.Queue; import java.util.Random; /** * @author jp *@date 2013-12-16 */ public class queuedemo { public static void printqueue(Queue queue) { while (queue.peek() != null ) { System.out.print(queue.remove() + " " ); } System.out.println(); } public static void main(String[] args) { Queue<Integer> queue = new LinkedList<Integer>(); Random random = new Random( 32 ); for ( int i = 0 ; i < 10 ; i++) queue.offer(random.nextInt(i + 10 )); printqueue(queue); Queue<Character> qCharacters = new LinkedList<Character>(); for ( char c: "GreatUniversity" .toCharArray()) qCharacters.offer(c); printqueue(qCharacters); } } |
Output:
7 7 5 9 9 2 9 3 0 2
G r e a t U n i v e r s i t y
说明:关于Queue的操作
Throws exception |
Returns special value |
|
Insert | add(e) |
offer(e) |
Remove | remove() |
poll() |
Examine | element() |
peek() |
add()& offer():在队尾插入元素,成功则返回true,失败则返回false,并且可能会会抛出IllegalStateException等;但offer()不会抛出任何异常;
remove()& poll():移除并返回对头元素,但在队列为空时,pull()返回null,而remove()则抛出NoSuchElementException;
element() & peek():不移除并返回对头元素,但在队列为空时,peek()返回null,而element()则抛出NoSuchElementException;
- About PriorityQueue:PriorityQueue与Queue的最基本的区别在于,优先级队列PriorityQueue具有顺序性;通常PriorityQueue用offer()方法进行插入元素的时候,它的默认顺序是对象的自然顺序(数字小到大,字母按字母表),但程序员可以通过提供自己的Comparator修改默认排序,以确保在通过peek(),poll(),remove()等方法获取元素时,得到的是具有最高优先级的的元素。另外,在学习数据结构堆排序的时候,老师跟我们讲得一般都是基于大顶堆而不是小顶堆,因为一般小顶堆通常用来实现维持优先级队列。下面举例说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.PriorityQueue; import java.util.Queue; import java.util.Random; import java.util.Set; /** * @author jp *@date 2013-12-16 */ public class priorityqueuedemo { public static void printqueue(Queue queue) { while (queue.peek() != null ) { System.out.print(queue.remove() + " " ); } System.out.println(); } public static void main(String[] args) { PriorityQueue<Integer> priorityQueue = new PriorityQueue<Integer>(); Random random = new Random( 32 ); for ( int i = 0 ;i < 10 ; i++) priorityQueue.offer(random.nextInt(i + 10 )); printqueue(priorityQueue); java.util.List<Integer> list = Arrays.asList( 12 , 14 , 15 , 16 , 17 , 18 , 19 , 20 ); priorityQueue = new PriorityQueue<Integer>(list); printqueue(priorityQueue); priorityQueue = new PriorityQueue<Integer>(list.size(), Collections.reverseOrder()); priorityQueue.addAll(list); printqueue(priorityQueue); String string = "i have a great dream" ; Set<Character> charset = new HashSet<Character>(); for ( char c: string.toCharArray()) { charset.add(c); } PriorityQueue<Character> pCharacters = new PriorityQueue<Character>(charset); printqueue(pCharacters); } } |
Output:
从最后一行可以看出:空格的优先级比一般的字母要高。下面看一个关于自己定义顺序,修改Comparator的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | import java.util.*; class ToDoList extends PriorityQueue<ToDoList.ToDoItem> { static class ToDoItem implements Comparable<ToDoItem> { private char primary; private int secondary; private String item; public ToDoItem(String s, char c, int i) { primary = c; secondary = i; item = s; } /* * @see java.lang.Comparable#compareTo(java.lang.Object) * @implements Comparabale,then define the CompareTo() * @function firstly compare "key value",then "secondary value"(+1,0,-1) */ public int compareTo(ToDoItem arg) { if (primary > arg.primary) return + 1 ; if (primary == arg.primary) if (secondary > arg.secondary) return + 1 ; else if (secondary == arg.secondary) return 0 ; return - 1 ; } public String toString() { return Character.toString(primary) + secondary + ": " + item; } } public void add(String s, char c, int i) { super .add( new ToDoItem(s, c, i)); } public static void main(String[] args) { ToDoList toDoList = new ToDoList(); toDoList.add( "allen" , 'a' , 2 ); toDoList.add( "jackson" , 'a' , 3 ); toDoList.add( "davil" , 'b' , 3 ); toDoList.add( "avily" , 'b' , 2 ); while (!toDoList.isEmpty()) { System.out.println(toDoList.remove()); } } } |
output:
a2: allen
a3: jackson
b2: avily
b3: davil
除了一般的Queue和PriorityQueue,还有一种叫做双端队列Deque,但它相对没那么常用,在此就不做相关介绍了,有兴趣的读者可以自行学习!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述