热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java的栈和队列实例分析

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

这篇文章主要讲解了“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=&#39;Sum&#39;, age=9}, Human{name=&#39;Nana&#39;, age=18}, Human{name=&#39;Amy&#39;, age=38}, Human{name=&#39;Lili&#39;, age=25}]
            //出列的时候按优先级出列
            System.out.println(priorityBlockingQueue.take());//Human{name=&#39;Sum&#39;, age=9}
            System.out.println(priorityBlockingQueue.take());//Human{name=&#39;Nana&#39;, age=18}
            System.out.println(priorityBlockingQueue.take());//Human{name=&#39;Lili&#39;, age=25}
            System.out.println(priorityBlockingQueue.take());//Human{name=&#39;Amy&#39;, 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=&#39;" + name + &#39;\&#39;&#39; +
                    ", age=" + age +
                    &#39;}&#39;;
        }
    
        @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=&#39;" + name + &#39;\&#39;&#39; +
                    &#39;}&#39;;
        }
        @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()));
        }
    }

    Java的栈和队列实例分析

    双端队列

    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的栈和队列实例分析这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程笔记,小编将为大家推送更多相关知识点的文章,欢迎关注!


    推荐阅读
    • 本文详细介绍了在Luat OS中如何实现C与Lua的混合编程,包括在C环境中运行Lua脚本、封装可被Lua调用的C语言库,以及C与Lua之间的数据交互方法。 ... [详细]
    • Hadoop MapReduce 实战案例:手机流量使用统计分析
      本文通过一个具体的Hadoop MapReduce案例,详细介绍了如何利用MapReduce框架来统计和分析手机用户的流量使用情况,包括上行和下行流量的计算以及总流量的汇总。 ... [详细]
    • LeetCode 102 - 二叉树层次遍历详解
      本文详细解析了LeetCode第102题——二叉树的层次遍历问题,提供了C++语言的实现代码,并对算法的核心思想和具体步骤进行了深入讲解。 ... [详细]
    • 本文基于Java官方文档进行了适当修改,旨在介绍如何实现一个能够同时处理多个客户端请求的服务端程序。在前文中,我们探讨了单客户端访问的服务端实现,而本篇将深入讲解多客户端环境下的服务端设计与实现。 ... [详细]
    • 深入解析 C++ 中的 String 和 Vector
      本文详细介绍了 C++ 编程语言中 String 和 Vector 的使用方法及特性,旨在帮助开发者更好地理解和应用这两个重要的容器。 ... [详细]
    • 本文探讨了异步编程的发展历程,从最初的AJAX异步回调到现代的Promise、Generator+Co以及Async/Await等技术。文章详细分析了Promise的工作原理及其源码实现,帮助开发者更好地理解和使用这一重要工具。 ... [详细]
    • 本文详细介绍了 Redis 中的主要数据类型,包括 String、Hash、List、Set、ZSet、Geo 和 HyperLogLog,并提供了每种类型的基本操作命令和应用场景。 ... [详细]
    • protobuf 使用心得:解析与编码陷阱
      本文记录了一次在广告系统中使用protobuf进行数据交换时遇到的问题及其解决过程。通过这次经历,我们将探讨protobuf的特性和编码机制,帮助开发者避免类似的陷阱。 ... [详细]
    • Flutter 核心技术与混合开发模式深入解析
      本文深入探讨了 Flutter 的核心技术,特别是其混合开发模式,包括统一管理模式和三端分离模式,以及混合栈原理。通过对比不同模式的优缺点,帮助开发者选择最适合项目的混合开发策略。 ... [详细]
    • egg实现登录鉴权(七):权限管理
      权限管理包含三部分:访问页面的权限,操作功能的权限和获取数据权限。页面权限:登录用户所属角色的可访问页面的权限功能权限:登录用户所属角色的可访问页面的操作权限数据权限:登录用户所属 ... [详细]
    • 函子(Functor)是函数式编程中的一个重要概念,它不仅是一个特殊的容器,还提供了一种优雅的方式来处理值和函数。本文将详细介绍函子的基本概念及其在函数式编程中的应用,包括如何通过函子控制副作用、处理异常以及进行异步操作。 ... [详细]
    • 在尝试加载支持推送通知的iOS应用程序的Ad Hoc构建时,遇到了‘no valid aps-environment entitlement found for application’的错误提示。本文将探讨此错误的原因及多种可能的解决方案。 ... [详细]
    • Maven + Spring + MyBatis + MySQL 环境搭建与实例解析
      本文详细介绍如何使用MySQL数据库进行环境搭建,包括创建数据库表并插入示例数据。随后,逐步指导如何配置Maven项目,整合Spring框架与MyBatis,实现高效的数据访问。 ... [详细]
    • 本文详细介绍了如何在Oracle VM VirtualBox中实现主机与虚拟机之间的数据交换,包括安装Guest Additions增强功能,以及如何利用这些功能进行文件传输、屏幕调整等操作。 ... [详细]
    • 使用TabActivity实现Android顶部选项卡功能
      本文介绍如何通过继承TabActivity来创建Android应用中的顶部选项卡。通过简单的步骤,您可以轻松地添加多个选项卡,并实现基本的界面切换功能。 ... [详细]
    author-avatar
    -不想醒来-县
    这个家伙很懒,什么也没留下!
    PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
    Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有