好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

一起来学习Java的栈和队列

?

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

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]

         //查看栈顶元素,并且移除,即出栈(先进后出)

         System.out.println(stack.pop()); //D

         System.out.println(stack); //[A, B, C]

         //入栈,和add方法执行的功能一样,就是返回值不同

         System.out.println(stack.push( "E" )); //返回入栈的元素 E

         System.out.println(stack); //[A, B, C, E]

     }

}

队列

阻塞队列

ArrayBlockingQueue : 不支持读写同时操作,底层基于数组的; LinkedBlockingQueue :支持读写同时操作,并发情况下,效率高,底层基于链表;

?

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

52

53

54

55

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,报空指针异常

         //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" ); //无返回值

 

         //队列满的情况下添加元素

         //arrayBlockingQueue.add("Sam");//报非法的状态异常

         //设置最大注阻塞时间,如果时间到了队列还是满的,就不再阻塞了

         arrayBlockingQueue.offer( "Daming" , 3 ,TimeUnit.SECONDS);

         System.out.println(arrayBlockingQueue); //[Lili, Amy, Nana]

         //真正阻塞的方法,如果队列一直是满的,就一直阻塞

         //arrayBlockingQueue.put("Lingling");//运行到这永远走不下去了,阻塞了

 

         //获取元素

         //获取队首元素不移除

         System.out.println(arrayBlockingQueue.peek()); //Lili

         //出队,获取队首元素并且移除

         System.out.println(arrayBlockingQueue.poll()); //Lili

         System.out.println(arrayBlockingQueue); //[Amy, Nana]

         //获取队首元素,并且移除

         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());

         //设置阻塞事件,如果队列为空,返回null,时间到了以后就不阻塞了

         System.out.println(arrayBlockingQueue.poll( 2 ,TimeUnit.SECONDS));

         //真正的阻塞,队列为空

         //System.out.println(arrayBlockingQueue.take());//执行到这里走不下去了

     }

}

SynchronousQueue :方便高效地进行线程间数据的传送,不会产生队列中数据争抢问题;

?

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

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();

         //创建一个线程,取数据:

         new Thread( new Runnable() {

             @Override

             public void run() {

                 while ( true ){

                     try {

                         System.out.println(sq.take());

                     } catch (InterruptedException e) {

                         e.printStackTrace();

                     }

                 }

             }

         }).start();

         //搞一个线程,往里面放数据:

         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 :带优先级的阻塞队列; 无界的队列,没有长度限制,但是在你不指定长度的时候,默认初始长度为11,也可以手动指定,当然随着数据不断的加入,底层(底层是数组Object[])会自动扩容,直到内存全部消耗殆尽了,导致 OutOfMemoryError内存溢出 程序才会结束; 不可以放入null元素的,不允许放入不可比较的对象(导致抛 ClassCastException ),对象必须实现内部比较器或者外部比较器;

?

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

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

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 ));

         //没有按优先级排列

         System.out.println(priorityBlockingQueue); //[Human{name='Sum', age=9}, Human{name='Nana', age=18}, Human{name='Amy', age=38}, Human{name='Lili', age=25}]

         //出列的时候按优先级出列

         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 ,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走; 当生产者线程调用put之类的方法加入元素时,会触发Delayed接口中的compareTo方法进行排序,也就是说队列中元素的顺序是按到期时间排序的,而非它们进入队列的顺序。排在队列头部的元素是最早到期的,越往后到期时间越晚; 消费者线程查看队列头部的元素,注意是查看不是取出。然后调用元素的getDelay方法,如果此方法返回的值小0或者等于0,则消费者线程会从队列中取出此元素,并进行处理。如果getDelay方法返回的值大于0,则消费者线程wait返回的时间值后,再从队列头部取出元素,此时元素应该已经到期; 不能将null元素放置到这种队列中; DelayQueue能做什么 淘宝订单业务:下单之后如果三十分钟之内没有付款就自动取消订单; 饿了吗订餐通知:下单成功后60s之后给用户发送短信通知; 关闭空闲连接。服务器中,有很多客户端的连接,空闲一段时间之后需要关闭之; 缓存。缓存中的对象,超过了空闲时间,需要从缓存中移出; 任务超时处理。在网络协议滑动窗口请求应答式交互时,处理超时未响应的请求等;

?

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

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

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 {

     //创建一个队列:

     DelayQueue<User> dq = new DelayQueue<>();

     //登录游戏:

     public void login(User user){

         dq.add(user);

         System.out.println( "用户:[" + user.getId() + "],[" + user.getName() + "]已经登录,预计下机时间为:" + user.getEndTime() );

     }

     //时间到,退出游戏,队列中移除:

     public void logout(){

         //打印队列中剩余的人:

         System.out.println(dq);

         try {

             User user = dq.take();

             System.out.println( "用户:[" + user.getId() + "],[" + user.getName() + "]上机时间到,自动退出游戏" );

         } catch (InterruptedException e) {

             e.printStackTrace();

         }

     }

     //获取在线人数:

     public int onlineSize(){

         return dq.size();

     }

     //这是main方法,程序的入口

     public static void main(String[] args) {

         //创建测试类对象:

         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 ));

         //一直监控

         while ( true ){

             //到期的话,就自动下线:

             test.logout();

             //队列中元素都被移除了的话,那么停止监控,停止程序即可

             if (test.onlineSize() == 0 ){

                 break ;

             }

         }

     }

}

class User implements Delayed {

     private int id; //用户id

     private String name; //用户名字

     private long endTime; //结束时间

     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) {

         //计算剩余时间 剩余时间小于0 <=0  证明已经到期

         return this .getEndTime() - System.currentTimeMillis();

     }

     @Override

     public int compareTo(Delayed o) {

         //队列中数据 到期时间的比较

         User other = (User)o;

         return ((Long)( this .getEndTime()))测试数据pareTo((Long)(other.getEndTime()));

     }

}

双端队列

?

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

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) {

         /*

         双端队列:

         Deque<E> extends Queue

         Queue一端放 一端取的基本方法  Deque是具备的

         在此基础上 又扩展了 一些 头尾操作(添加,删除,获取)的方法

          */

         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]

     }

}

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注的更多内容!  

原文链接:https://blog.csdn.net/qq_33445829/article/details/123614633

查看更多关于一起来学习Java的栈和队列的详细内容...

  阅读:19次