首页 > 编程语言 >Java集合篇之逐渐被遗忘的Stack,手写一个栈你会吗?

Java集合篇之逐渐被遗忘的Stack,手写一个栈你会吗?

时间:2024-02-19 09:00:10浏览次数:27  
标签:Java 入栈 int stacks System stack push 手写 Stack

正月初九,开工大吉!
2024年,更上一层楼!

写在开头

其实在List的继承关系中,除了ArrayList和LinkedList之外,还有另外一个集合类stack(栈),它继承自vector,线程安全,先进后出,随着Java并发编程的发展,它在很多应用场景下被逐渐替代,成为了Java的遗落之类。不过,stack在数据结构中仍有一席之地,因此,我们有必要也应该好好的学一下!

Collection和Collections的区别?

在开始学习栈之前,先来解决一下之前一个网友在评论区问的问题:

Collection和Collections有什么区别?

虽然这两个类都在java.util包下,虽然只有一字之差,但它们的差别还是挺大的!
Collection 是JDK中集合层次结构中的最根本的接口。定义了集合类的基本方法。源码中的解释:

 * The root interface in the <i>collection hierarchy</i>.  A collection
 * represents a group of objects, known as its <i>elements</i>.  Some
 * collections allow duplicate elements and others do not.  Some are ordered
 * and others unordered.  The JDK does not provide any <i>direct</i>
 * implementations of this interface: it provides implementations of more
 * specific subinterfaces like <tt>Set</tt> and <tt>List</tt>.  This interface
 * is typically used to pass collections around and manipulate them where
 * maximum generality is desired.

Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法,不能实例化,Collection 集合框架的工具类。源码中的解释:

* This class consists exclusively of static methods that operate on or return
* collections.  It contains polymorphic algorithms that operate on
* collections, "wrappers", which return a new collection backed by a
* specified collection, and a few other odds and ends.

stack(栈)

栈(stack)是一种先进后出(Last In First Out,LIFO)的数据结构,类比于现实生活中的子弹上膛、泡泡圈。栈具有两个基本操作:入栈(push)和出栈(pop)。入栈表示将元素放入栈顶,而出栈表示从栈顶取出元素。

动图图解-入栈(push)

动图图解-出栈(pop)

在Java的工具包中其实帮我们封装好了一个类,java.util.Stack,它所提供的方法并不多,我们通过一个小示例感受一下。

【代码示例1】

Stack<String> stacks = new Stack<>();
//push方法入栈
 stacks.push("开");
 stacks.push("工");
 stacks.push("大");
 stacks.push("吉");
 stacks.push("!");
 System.out.println(stacks);
 //pop栈顶元素出栈
 String pop = stacks.pop();
 System.out.println(pop);
 //查看栈顶元素
 String peek = stacks.peek();
 System.out.println(peek);
 //判断堆栈是否为空
 boolean empty = stacks.empty();
 System.out.println(empty);
 //查看元素在堆栈中的位置
 int index = stacks.search("开");
 System.out.println(index);

输出:

[开, 工, 大, 吉, !]
!
吉
false
4

手写一个stack(堆栈)

通过上面的代码示例我们了解了一个栈所具备的功能特点,根据它的特点,我们尝试一下手写一个栈!
首先,准备一个数组用来存储元素,可以定义为Object,这样支持多数据类型,我们这里直接选用int类型的好嘞。
自定义栈-源码:

/**
 * @ClassName Stack
 * @Description 手写一个int类型的堆栈
 * @Author hzm
 * @Date 2024/2/18 14:21
 * @Version 1.0
 */
public class Stack {
    private int arr[];
    private int top;
    private int capacity;

    /**
     * 提供一个有参构造,初始化栈
     * @param size
     */
    public Stack(int size) {
        this.arr = new int[size];
        this.top = -1;
        this.capacity = size;
    }

    /**
     * 入栈
     * @param p
     */
    public void push(int p) {
        if (isFull()) {
            System.out.println("堆栈空间溢出\n程序终止\n");
            System.exit(1);
        }

        System.out.println("入栈:" + p);
        arr[++top] = p;
    }

    /**
     * 出栈
     * @return
     */
    public int pop() {
        if (isEmpty()) {
            System.out.println("空栈,不可POP");
            System.exit(1);
        }
        return arr[top--];
    }

    /**
     * 判断栈是否已满
     * @return
     */
    public Boolean isFull() {
        return top == capacity - 1;
    }

    /**
     * 判断栈是否为空
     * @return
     */
    public Boolean isEmpty() {
        return top == -1;
    }

    /**
     * 遍历栈内元素
     */
    public void printStack() {
        for (int i = 0; i <= top; i++) {
            System.out.println(arr[i]);
        }
    }

    /**
     * 返回栈的大小
     * @return
     */
    public int size() {
        return top + 1;
    }

    /**
     * 查看栈顶元素
     * @return
     */
    public void peek(){
        System.out.println("栈顶元素:" + arr[top]);
    }
}

测试类中调用手写的这个stack:

public class Test {
    public static void main(String[] args) {
        Stack stack = new Stack(5);
        //入栈
        stack.push(1);
        stack.push(2);
        stack.push(3);
        stack.push(4);
        stack.push(5);
        //出栈
        int pop = stack.pop();
        System.out.println("出栈:"+ pop);
        //查看栈的大小
        int size = stack.size();
        System.out.println("栈容量:" + size);
        //查看栈顶元素
        stack.peek();
        //打印栈内元素
        stack.printStack();
    }
}

输出:

入栈:1
入栈:2
入栈:3
入栈:4
入栈:5
出栈:5
栈容量:4
栈顶元素:4
1
2
3
4

好了,今天的栈内容就写到这里吧,大家私下里可以找找leetcode上关于栈的算法题做做,深刻感受一下哈!

结尾彩蛋

如果本篇博客对您有一定的帮助,大家记得留言+点赞+收藏呀。原创不易,转载请联系Build哥!

标签:Java,入栈,int,stacks,System,stack,push,手写,Stack
From: https://www.cnblogs.com/JavaBuild/p/18020340

相关文章

  • 深入了解 Java 方法和参数的使用方法
    Java方法简介方法是一块仅在调用时运行的代码。您可以将数据(称为参数)传递到方法中。方法用于执行特定的操作,它们也被称为函数。使用方法的原因重用代码:定义一次代码,多次使用。提高代码的结构化和可读性。将代码分解成更小的模块,易于维护和理解。创建方法方法必须在类内......
  • 监控Java虚拟线程
    目录监控Java虚拟线程简介虚拟线程监控的具体细节跟踪牵制线程(pinnedthreads)我的框架如何使用虚拟线程?监控ForkJoinPool结论参考监控Java虚拟线程开发便利性与运行高效性简介在我之前的文章中,我们已经讨论了什么是虚拟线程(VTs),他们与物理线程(PTs)之间的区别,以及如......
  • java 获取请求request,并返回请求的url
    StringwebStr=getRequest().getScheme()+"......
  • 运行 Java 文件
    编译javacHelloWorld.java#获得Java字节码文件HelloWorld.class运行javaHelloWorld#运行当前目录下的HelloWorld.class文件附加说明如果你的Java类在包内,你需要将package声明添加到你的Java文件顶部,并且在编译和运行时,你需要指定完整的类路径。假设你的......
  • JavaSE---Random
    java.util.Random概述Aninstanceofthisclassisusedtogenerateastreamofpseudorandomnumbers. Random实例用来生成伪随机数;Theclassusesa48-bitseed,whichismodifiedusingalinearcongruentialformula. (SeeDonaldKnuth,TheArtofComputerPr......
  • java自定义中文排序比较器
    1、先看看排序结果 2、自定义中文比较器//Comparator<String[]>中String[]表示的是每一行数据classStringArrayComparatorimplementsComparator<String[]>{privatefinalList<SortDTO>sortDTOList;//排序信息集合privatefinalCollatorcollator=Coll......
  • Java21 + SpringBoot3使用Spring Security时如何在子线程中获取到认证信息
    目录前言原因分析解决方案方案1:手动设置线程中的认证信息方案2:使用DelegatingSecurityContextRunnable创建线程方案3:修改SpringSecurity安全策略通过设置JVM参数修改安全策略通过SecurityContextHolder修改安全策略总结前言近日心血来潮想做一个开源项目,目标是做一款可以适配多......
  • java实现幂等性校验
    我们在做web应用的时候通常会遇到前端提交按钮重复点击的场景,在某些新增操作上就需要做幂等性限制来保证数据的可靠性。下面来用javaaop实现幂等性校验。一:首先我们需要一个自定义注解packagecom.yuku.yuku_erp.annotation;importjava.lang.annotation.*;/***@author......
  • Java集合篇之深入解析LinkedList
    写在开头作为ArrayList的同门师兄弟,LinkedList的师门地位逊色不少,除了在做算法题的时候我们会用到它之外,在实际的开发工作中我们极少使用它,就连它的创造者都说:“Iwroteit,andIneveruseit”,想想颇有点好笑,但这并不影响我们去学习它,个人认为它底层的链表逻辑对于我们代码思想......
  • Java是值传递
    一、定义值传递:当⼀个参数按照值的⽅式在两个⽅法之间传递时,调⽤者和被调⽤者其实是⽤的两个不同的变量——被调⽤者中的变量(原始值)是调⽤者中变量的⼀份拷⻉,对它们当中的任何⼀个变量修改都不会影响到另外⼀个变量。引用传递:当⼀个参数按照引⽤传递的⽅式在两个⽅法之间传递时,......