一起來學(xué)習(xí)Java的棧和隊(duì)列
棧
package com.yuzhenc.collection;
import java.util.Stack;
/**
* @author: yuzhenc
* @date: 2022-03-20 15:41:36
* @desc: com.yuzhenc.collection
* @version: 1.0
*/
public class Test26 {
public static void main(String[] args) {
Stack<String> stack = new Stack<>();
stack.add("A");
stack.add("B");
stack.add("C");
stack.add("D");
System.out.println(stack);//[A, B, C, D]
//判斷棧是否為空
System.out.println(stack.empty());//false
//查看棧頂元素,不會移除
System.out.println(stack.peek());//D
System.out.println(stack);//[A, B, C, D]
//查看棧頂元素,并且移除,即出棧(先進(jìn)后出)
System.out.println(stack.pop());//D
System.out.println(stack);//[A, B, C]
//入棧,和add方法執(zhí)行的功能一樣,就是返回值不同
System.out.println(stack.push("E"));//返回入棧的元素 E
System.out.println(stack);//[A, B, C, E]
}
}
隊(duì)列
阻塞隊(duì)列
ArrayBlockingQueue: 不支持讀寫同時操作,底層基于數(shù)組的;LinkedBlockingQueue:支持讀寫同時操作,并發(fā)情況下,效率高,底層基于鏈表;
package com.yuzhenc.collection;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;
/**
* @author: yuzhenc
* @date: 2022-03-20 16:00:22
* @desc: com.yuzhenc.collection
* @version: 1.0
*/
public class Test27 {
public static void main(String[] args) throws InterruptedException {
ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(3);
//添加元素
//不可以添加null,報(bào)空指針異常
//arrayBlockingQueue.add(null);
//arrayBlockingQueue.offer(null);
//arrayBlockingQueue.put(null);
//正常添加元素
System.out.println(arrayBlockingQueue.add("Lili"));//true
System.out.println(arrayBlockingQueue.offer("Amy"));//true
arrayBlockingQueue.put("Nana");//無返回值
//隊(duì)列滿的情況下添加元素
//arrayBlockingQueue.add("Sam");//報(bào)非法的狀態(tài)異常
//設(shè)置最大注阻塞時間,如果時間到了隊(duì)列還是滿的,就不再阻塞了
arrayBlockingQueue.offer("Daming", 3,TimeUnit.SECONDS);
System.out.println(arrayBlockingQueue);//[Lili, Amy, Nana]
//真正阻塞的方法,如果隊(duì)列一直是滿的,就一直阻塞
//arrayBlockingQueue.put("Lingling");//運(yùn)行到這永遠(yuǎn)走不下去了,阻塞了
//獲取元素
//獲取隊(duì)首元素不移除
System.out.println(arrayBlockingQueue.peek());//Lili
//出隊(duì),獲取隊(duì)首元素并且移除
System.out.println(arrayBlockingQueue.poll());//Lili
System.out.println(arrayBlockingQueue);//[Amy, Nana]
//獲取隊(duì)首元素,并且移除
System.out.println(arrayBlockingQueue.take());//Amy
System.out.println(arrayBlockingQueue);//[Nana]
//清空元素
arrayBlockingQueue.clear();
System.out.println(arrayBlockingQueue);//[]
System.out.println(arrayBlockingQueue.peek());
System.out.println(arrayBlockingQueue.poll());
//設(shè)置阻塞事件,如果隊(duì)列為空,返回null,時間到了以后就不阻塞了
System.out.println(arrayBlockingQueue.poll(2,TimeUnit.SECONDS));
//真正的阻塞,隊(duì)列為空
//System.out.println(arrayBlockingQueue.take());//執(zhí)行到這里走不下去了
}
}
SynchronousQueue:方便高效地進(jìn)行線程間數(shù)據(jù)的傳送,不會產(chǎn)生隊(duì)列中數(shù)據(jù)爭搶問題;
package com.yuzhenc.collection;
import java.util.concurrent.SynchronousQueue;
/**
* @author: yuzhenc
* @date: 2022-03-20 21:06:47
* @desc: com.yuzhenc.collection
* @version: 1.0
*/
public class Test28 {
public static void main(String[] args) {
SynchronousQueue sq = new SynchronousQueue();
//創(chuàng)建一個線程,取數(shù)據(jù):
new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
System.out.println(sq.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
//搞一個線程,往里面放數(shù)據(jù):
new Thread(new Runnable() {
@Override
public void run() {
try {
sq.put("aaa");
sq.put("bbb");
sq.put("ccc");
sq.put("ddd");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
PriorityBlockingQueue:帶優(yōu)先級的阻塞隊(duì)列;- 無界的隊(duì)列,沒有長度限制,但是在你不指定長度的時候,默認(rèn)初始長度為11,也可以手動指定,當(dāng)然隨著數(shù)據(jù)不斷的加入,底層(底層是數(shù)組Object[])會自動擴(kuò)容,直到內(nèi)存全部消耗殆盡了,導(dǎo)致 OutOfMemoryError內(nèi)存溢出 程序才會結(jié)束;
- 不可以放入null元素的,不允許放入不可比較的對象(導(dǎo)致拋
ClassCastException),對象必須實(shí)現(xiàn)內(nèi)部比較器或者外部比較器;
package com.yuzhenc.collection;
import java.util.concurrent.PriorityBlockingQueue;
/**
* @author: yuzhenc
* @date: 2022-03-20 21:16:56
* @desc: com.yuzhenc.collection
* @version: 1.0
*/
public class Test29 {
public static void main(String[] args) throws InterruptedException {
PriorityBlockingQueue<Human> priorityBlockingQueue = new PriorityBlockingQueue<>();
priorityBlockingQueue.put(new Human("Lili",25));
priorityBlockingQueue.put(new Human("Nana",18));
priorityBlockingQueue.put(new Human("Amy",38));
priorityBlockingQueue.put(new Human("Sum",9));
//沒有按優(yōu)先級排列
System.out.println(priorityBlockingQueue);//[Human{name='Sum', age=9}, Human{name='Nana', age=18}, Human{name='Amy', age=38}, Human{name='Lili', age=25}]
//出列的時候按優(yōu)先級出列
System.out.println(priorityBlockingQueue.take());//Human{name='Sum', age=9}
System.out.println(priorityBlockingQueue.take());//Human{name='Nana', age=18}
System.out.println(priorityBlockingQueue.take());//Human{name='Lili', age=25}
System.out.println(priorityBlockingQueue.take());//Human{name='Amy', age=38}
}
}
class Human implements Comparable <Human> {
String name;
int age;
public Human() {}
public Human(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Human{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Human o) {
return this.age-o.age;
}
DelayQueue:DelayQueue是一個無界的BlockingQueue,用于放置實(shí)現(xiàn)了Delayed接口的對象,其中的對象只能在其到期時才能從隊(duì)列中取走;- 當(dāng)生產(chǎn)者線程調(diào)用put之類的方法加入元素時,會觸發(fā)Delayed接口中的compareTo方法進(jìn)行排序,也就是說隊(duì)列中元素的順序是按到期時間排序的,而非它們進(jìn)入隊(duì)列的順序。排在隊(duì)列頭部的元素是最早到期的,越往后到期時間越晚;
- 消費(fèi)者線程查看隊(duì)列頭部的元素,注意是查看不是取出。然后調(diào)用元素的getDelay方法,如果此方法返回的值?。盎蛘叩扔冢?,則消費(fèi)者線程會從隊(duì)列中取出此元素,并進(jìn)行處理。如果getDelay方法返回的值大于0,則消費(fèi)者線程wait返回的時間值后,再從隊(duì)列頭部取出元素,此時元素應(yīng)該已經(jīng)到期;
- 不能將null元素放置到這種隊(duì)列中;
- DelayQueue能做什么
- 淘寶訂單業(yè)務(wù):下單之后如果三十分鐘之內(nèi)沒有付款就自動取消訂單;
- 餓了嗎訂餐通知:下單成功后60s之后給用戶發(fā)送短信通知;
- 關(guān)閉空閑連接。服務(wù)器中,有很多客戶端的連接,空閑一段時間之后需要關(guān)閉之;
- 緩存。緩存中的對象,超過了空閑時間,需要從緩存中移出;
- 任務(wù)超時處理。在網(wǎng)絡(luò)協(xié)議滑動窗口請求應(yīng)答式交互時,處理超時未響應(yīng)的請求等;
package com.yuzhenc.collection;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
/**
* @author: yuzhenc
* @date: 2022-03-20 21:43:32
* @desc: com.yuzhenc.collection
* @version: 1.0
*/
public class Test30 {
//創(chuàng)建一個隊(duì)列:
DelayQueue<User> dq = new DelayQueue<>();
//登錄游戲:
public void login(User user){
dq.add(user);
System.out.println("用戶:[" + user.getId() +"],[" + user.getName() + "]已經(jīng)登錄,預(yù)計(jì)下機(jī)時間為:" + user.getEndTime() );
}
//時間到,退出游戲,隊(duì)列中移除:
public void logout(){
//打印隊(duì)列中剩余的人:
System.out.println(dq);
try {
User user = dq.take();
System.out.println("用戶:[" + user.getId() +"],[" + user.getName() + "]上機(jī)時間到,自動退出游戲");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//獲取在線人數(shù):
public int onlineSize(){
return dq.size();
}
//這是main方法,程序的入口
public static void main(String[] args) {
//創(chuàng)建測試類對象:
Test30 test = new Test30();
//添加登錄的用戶:
test.login(new User(1,"張三",System.currentTimeMillis()+5000));
test.login(new User(2,"李四",System.currentTimeMillis()+2000));
test.login(new User(3,"王五",System.currentTimeMillis()+10000));
//一直監(jiān)控
while(true){
//到期的話,就自動下線:
test.logout();
//隊(duì)列中元素都被移除了的話,那么停止監(jiān)控,停止程序即可
if(test.onlineSize() == 0){
break;
}
}
}
}
class User implements Delayed {
private int id;//用戶id
private String name;//用戶名字
private long endTime;//結(jié)束時間
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getEndTime() {
return endTime;
}
public void setEndTime(long endTime) {
this.endTime = endTime;
}
public User(int id, String name, long endTime) {
this.id = id;
this.name = name;
this.endTime = endTime;
}
//只包裝用戶名字就可以
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
@Override
public long getDelay(TimeUnit unit) {
//計(jì)算剩余時間 剩余時間小于0 <=0 證明已經(jīng)到期
return this.getEndTime() - System.currentTimeMillis();
}
@Override
public int compareTo(Delayed o) {
//隊(duì)列中數(shù)據(jù) 到期時間的比較
User other = (User)o;
return ((Long)(this.getEndTime())).compareTo((Long)(other.getEndTime()));
}
}

雙端隊(duì)列
package com.yuzhenc.collection;
import java.util.Deque;
import java.util.LinkedList;
/**
* @author: yuzhenc
* @date: 2022-03-20 22:03:36
* @desc: com.yuzhenc.collection
* @version: 1.0
*/
public class Test31 {
public static void main(String[] args) {
/*
雙端隊(duì)列:
Deque<E> extends Queue
Queue一端放 一端取的基本方法 Deque是具備的
在此基礎(chǔ)上 又?jǐn)U展了 一些 頭尾操作(添加,刪除,獲?。┑姆椒?
*/
Deque<String> d = new LinkedList<>() ;
d.offer("A");
d.offer("B");
d.offer("C");
System.out.println(d);//[A, B, C]
d.offerFirst("D");
d.offerLast("E");
System.out.println(d);//[D, A, B, C, E]
System.out.println(d.poll());//D
System.out.println(d);//[A, B, C, E]
System.out.println(d.pollFirst());//A
System.out.println(d.pollLast());//E
System.out.println(d);//[B, C]
}
}
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
- java 數(shù)據(jù)結(jié)構(gòu)之棧與隊(duì)列
- java 數(shù)據(jù)結(jié)構(gòu)中棧和隊(duì)列的實(shí)例詳解
- Java深入了解數(shù)據(jù)結(jié)構(gòu)之棧與隊(duì)列的詳解
- Java 棧和隊(duì)列的相互轉(zhuǎn)換詳解
- Java棧和基礎(chǔ)隊(duì)列的實(shí)現(xiàn)詳解
- Java?棧與隊(duì)列實(shí)戰(zhàn)真題訓(xùn)練
- Java 棧與隊(duì)列超詳細(xì)分析講解
- Java使用跳轉(zhuǎn)結(jié)構(gòu)實(shí)現(xiàn)隊(duì)列和棧流程詳解
- Java線性結(jié)構(gòu)中棧、隊(duì)列和串的基本概念和特點(diǎn)詳解
- Java常見的數(shù)據(jù)結(jié)構(gòu)之棧和隊(duì)列詳解
- Java 棧和隊(duì)列的交互實(shí)現(xiàn)
相關(guān)文章
Mybatis?大數(shù)據(jù)量批量寫優(yōu)化的案例詳解
這篇文章主要介紹了Mybatis?大數(shù)據(jù)量批量寫優(yōu)化的示例代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-05-05
SWT(JFace)體驗(yàn)之FillLayout布局
FillLayout是非常簡單的一種布局方式,它會以同樣大小對父組件中的子組件進(jìn)行布局,這些子組件將以一行或一列的形式排列。2009-06-06
SpringCache常用注解及key中參數(shù)值為null問題解析
這篇文章主要介紹了SpringCache常用注解及key中參數(shù)值為null的問題解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
SpringBoot整合Drools規(guī)則引擎動態(tài)生成業(yè)務(wù)規(guī)則的實(shí)現(xiàn)
本文主要介紹了SpringBoot整合Drools規(guī)則引擎動態(tài)生成業(yè)務(wù)規(guī)則的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-12-12
Springboot 如何指定獲取自己寫的配置properties文件的值
這篇文章主要介紹了Springboot 如何指定獲取自己寫的配置properties文件的值,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
Java獲取環(huán)境變量(System.getenv)的方法
本文主要介紹了Java獲取環(huán)境變量(System.getenv)的方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05

