java集合类(六)About Queue

接上篇“java集合类(五)About Map”

     终于来到了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的基础例子:
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()等方法获取元素时,得到的是具有最高优先级的的元素。另外,在学习数据结构堆排序的时候,老师跟我们讲得一般都是基于大顶堆而不是小顶堆,因为一般小顶堆通常用来实现维持优先级队列。下面举例说明:
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的例子:

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,但它相对没那么常用,在此就不做相关介绍了,有兴趣的读者可以自行学习!

  

原文地址:https://www.cnblogs.com/allenpengyu/p/3467199.html