千家信息网

Java的栈和队列实例分析

发表于:2024-11-26 作者:千家信息网编辑
千家信息网最后更新 2024年11月26日,这篇文章主要讲解了"Java的栈和队列实例分析",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Java的栈和队列实例分析"吧!栈package com.
千家信息网最后更新 2024年11月26日Java的栈和队列实例分析

这篇文章主要讲解了"Java的栈和队列实例分析",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Java的栈和队列实例分析"吧!

    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 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:支持读写同时操作,并发情况下,效率高,底层基于链表;

    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 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:方便高效地进行线程间数据的传送,不会产生队列中数据争抢问题;

    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),对象必须实现内部比较器或者外部比较器;

    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 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  {    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之后给用户发送短信通知;

      • 关闭空闲连接。服务器中,有很多客户端的连接,空闲一段时间之后需要关闭之;

      • 缓存。缓存中的对象,超过了空闲时间,需要从缓存中移出;

      • 任务超时处理。在网络协议滑动窗口请求应答式交互时,处理超时未响应的请求等;

    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 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())).compareTo((Long)(other.getEndTime()));    }}

    双端队列

    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 extends Queue        Queue一端放 一端取的基本方法  Deque是具备的        在此基础上 又扩展了 一些 头尾操作(添加,删除,获取)的方法         */        Deque 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]    }}

    感谢各位的阅读,以上就是"Java的栈和队列实例分析"的内容了,经过本文的学习后,相信大家对Java的栈和队列实例分析这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

    0