1.什么是隊(duì)列育勺?
隊(duì)列是數(shù)據(jù)結(jié)構(gòu)中比較重要的一種類型(是一種數(shù)據(jù)結(jié)構(gòu))但荤,它支持 FIFO罗岖,尾部添加、頭部刪除(先進(jìn)隊(duì)列的元素先出隊(duì)列)腹躁,跟我們生活中的排隊(duì)類似桑包。
2.什么情況下使用隊(duì)列?
一般情況下纺非,如果是對(duì)一些及時(shí)消息的處理哑了,并且處理時(shí)間很短的情況下是不需要隊(duì)列的,直接阻塞式的方法調(diào)用就可以了烧颖。但是如果在消息處理的時(shí)候特別費(fèi)時(shí)間弱左,這個(gè)時(shí)候如果有新消息來(lái)了,就只能處于阻塞狀態(tài)炕淮,造成用戶等待拆火。這個(gè)時(shí)候便需要引入隊(duì)列了。當(dāng)接收到消息后涂圆,先把消息房貸隊(duì)列中们镜,然后再用行的線程進(jìn)行處理,這個(gè)時(shí)候就不會(huì)有消息阻塞了润歉。
3.隊(duì)列介紹:
隊(duì)列有兩種:① 單隊(duì)列 : 就是常見(jiàn)的隊(duì)列模狭,每次添加元素時(shí),都是添加對(duì)隊(duì)尾踩衩。
② 循環(huán)隊(duì)列(暫不介紹)
4.隊(duì)列Queue
add 增加一個(gè)元索 如果隊(duì)列已滿嚼鹉,則拋出一個(gè)IIIegaISlabEepeplian異常
remove 移除并返回隊(duì)列頭部的元素 如果隊(duì)列為空,則拋出一個(gè)NoSuchElementException異常
element 返回隊(duì)列頭部的元素 如果隊(duì)列為空驱富,則拋出一個(gè)NoSuchElementException異常
offer 添加一個(gè)元素并返回true 如果隊(duì)列已滿反砌,則返回false
poll 移除并返問(wèn)隊(duì)列頭部的元素 如果隊(duì)列為空,則返回null
peek 返回隊(duì)列頭部的元素 如果隊(duì)列為空萌朱,則返回null
put 添加一個(gè)元素 如果隊(duì)列滿宴树,則阻塞
take 移除并返回隊(duì)列頭部的元素 如果隊(duì)列為空,則阻塞
Java 集合中的 Queue 繼承自 Collection 接口 晶疼,Deque, LinkedList, PriorityQueue, BlockingQueue 等類都實(shí)現(xiàn)了它酒贬。
Queue 用來(lái)存放 等待處理元素 的集合,這種場(chǎng)景一般用于緩沖翠霍、并發(fā)訪問(wèn)锭吨。
除了繼承 Collection 接口的一些方法,Queue 還添加了額外的 添加寒匙、刪除零如、查詢操作躏将。
添加、刪除考蕾、查詢這些個(gè)操作都提供了兩種形式祸憋,其中一種在操作失敗時(shí)直接拋出異常,而另一種則返回一個(gè)特殊的值:
Queue 方法介紹:
1.add(E), offer(E) 在尾部添加:
boolean add(E e);
boolean offer(E e);
他們的共同之處是建議實(shí)現(xiàn)類禁止添加 null 元素肖卧,否則會(huì)報(bào)空指針 NullPointerException蚯窥;
不同之處在于 add() 方法在添加失敗(比如隊(duì)列已滿)時(shí)會(huì)報(bào) 一些運(yùn)行時(shí)錯(cuò)誤 錯(cuò)塞帐;而 offer() 方法即使在添加失敗時(shí)也不會(huì)奔潰拦赠,只會(huì)返回 false。
2016.11.21 添加
注意
Queue 是個(gè)接口葵姥,它提供的 add, offer 方法初衷是希望子類能夠禁止添加元素為 null荷鼠,這樣可以避免在查詢時(shí)返回 null 究竟是正確還是錯(cuò)誤。
事實(shí)上大多數(shù) Queue 的實(shí)現(xiàn)類的確響應(yīng)了 Queue 接口的規(guī)定榔幸,比如 ArrayBlockingQueue允乐,PriorityBlockingQueue 等等。
但還是有一些實(shí)現(xiàn)類沒(méi)有這樣要求牡辽,比如 LinkedList喳篇。
感謝 sumsear 指出。
2.remove(), poll() 刪除并返回頭部:
E remove();
E poll();
當(dāng)隊(duì)列為空時(shí) remove() 方法會(huì)報(bào) NoSuchElementException 錯(cuò); 而 poll() 不會(huì)奔潰态辛,只會(huì)返回 null麸澜。
3.element(), peek() 獲取但不刪除:
E element();
E peek();
當(dāng)隊(duì)列為空時(shí) element() 拋出異常;peek() 不會(huì)奔潰奏黑,只會(huì)返回 null炊邦。
其他
1.雖然 LinkedList 沒(méi)有禁止添加 null,但是一般情況下 Queue 的實(shí)現(xiàn)類都不允許添加 null 元素熟史,為啥呢馁害?因?yàn)?poll(), peek() 方法在異常的時(shí)候會(huì)返回 null,你添加了 null 以后蹂匹,當(dāng)獲取時(shí)不好分辨究竟是否正確返回碘菜。
2.Queue 一般都是 FIFO 的,但是也有例外限寞,比如優(yōu)先隊(duì)列 priority queue(它的順序是根據(jù)自然排序或者自定義 comparator 的)忍啸;再比如 LIFO 的隊(duì)列(跟棧一樣,后來(lái)進(jìn)去的先出去)履植。
不論進(jìn)入计雌、出去的先后順序是怎樣的,使用 remove()玫霎,poll() 方法操作的都是 頭部 的元素凿滤;而插入的位置則不一定是在隊(duì)尾了妈橄,不同的 queue 會(huì)有不同的插入邏輯。
5.代碼示例:
import java.util.LinkedList;
import java.util.Queue;
import org.junit.Before;
import org.junit.Test;
/**
隊(duì)列測(cè)試:實(shí)現(xiàn)類使用LinkedList
Queue也有很多其他的實(shí)現(xiàn)類翁脆,比如java.util.concurrent.LinkedBlockingQueue眷蚓。
-
LinkedBlockingQueue是一個(gè)阻塞的線程安全的隊(duì)列,底層實(shí)現(xiàn)也是使用鏈?zhǔn)浇Y(jié)構(gòu)鹃祖。
*/
public class TestQuene {// 定義一個(gè)隊(duì)列
Queue<String> queue;@Before
public void before() {
// 實(shí)例化隊(duì)列變量
queue = new LinkedList<String>();// add方法向隊(duì)列中添加元素,返回布爾值溪椎,add方法添加失敗時(shí)會(huì)拋異常,不推薦使用 // queue.add("1"); // queue.add("2"); // queue.add("3"); // queue.add("4"); // queue.add("5"); // offer方法向隊(duì)列中添加元素普舆,返回布爾值 queue.offer("a"); queue.offer("b"); queue.offer("c"); queue.offer("d"); queue.offer("e");
}
// poll方法移除隊(duì)列首個(gè)元素并返回恬口,若隊(duì)列為空,返回null
@Test
public void test1() {
// 彈出元素
String pollEle = queue.poll(); // 先進(jìn)先出,彈出了a
System.out.println(pollEle); // a
System.out.println(queue); // [b, c, d, e]
}// remove方法移除首個(gè)元素并返回,若隊(duì)列為空,會(huì)拋出異常:NoSuchElementException沼侣,不推薦使用
@Test
public void test2() {
// 彈出元素
String remove = queue.remove(); // 先進(jìn)先出,彈出了a
System.out.println(remove); // a
System.out.println(queue); // [b, c, d, e]
}// peek方法返回隊(duì)列首個(gè)元素祖能,但不移除,若隊(duì)列為空蛾洛,返回null
@Test
public void test3() {
// 查看首個(gè)元素
String peek = queue.peek(); // 首個(gè)元素是a,最先加入
System.out.println(peek); // a
System.out.println(queue); // [a, b, c, d, e]
}// element方法返回隊(duì)列的頭元素养铸,但不移除,若隊(duì)列為空轧膘,會(huì)拋出異常:NoSuchElementException钞螟,不推薦使用
@Test
public void test4() {
// 查看首個(gè)元素
String element = queue.element();
System.out.println(element); // a
System.out.println(queue); // [a, b, c, d, e]
}
}
-->隊(duì)列的結(jié)合使用