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

简介: 总之,虽然在日常开发中,`java.util.Stack`正逐渐被其他类如 `Deque`接口的实现所取代,但手写一个栈(无论是基于数组还是链表)都是一次很好的编程练习,它可以帮助开发者更加深入地理解栈这种数据结构的工作原理和各种操作。

在Java集合框架中,Stack类是一个后入先出(LIFO)的堆栈,但在现代的Java开发中,这个类往往被 Deque接口的实现类(如 LinkedListArrayDeque)所替代。不过,手写一个栈结构不仅是对数据结构理解的一种体现,也是检验编程能力的一个很好的例子。

为了实现一个基础的栈,我们可以使用数组或链表作为内部存储结构。以下是使用数组实现的一个简单的栈结构,考虑到易懂和实用性,我会展示一个简易版本的栈实现,它将支持基本的操作:压栈(push)、弹栈(pop)、查看栈顶元素(peek)和检查栈是否为空(isEmpty)。首先,我们定义栈的数据结构如下:

public class CustomStack<E> {
    private Object[] array;
    private int size;
    private static final int DEFAULT_CAPACITY = 10;

    public CustomStack() {
        array = new Object[DEFAULT_CAPACITY];
        size = 0;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public E peek() {
        if (isEmpty()) {
            throw new EmptyStackException();
        }
        return (E) array[size - 1];
    }

    public E pop() {
        E element = peek();
        array[--size] = null; // 防止内存泄漏
        return element;
    }

    public void push(E item) {
        ensureCapacity();
        array[size++] = item;
    }

    private void ensureCapacity() {
        if (size >= array.length) {
            int newSize = array.length * 2;
            array = Arrays.copyOf(array, newSize);
        }
    }

    // 更多实用方法(例如返回栈的大小,遍历等)可以根据需要增加
}

在这个 CustomStack类中,我们使用了泛型来提供类型安全,并且内部使用了一个 Object类型的数组来存储栈中的元素。数组的初始化大小为 DEFAULT_CAPACITY,这是我们预设的一个值,在数组容量不够时,通过 ensureCapacity方法进行扩容。

push方法将元素压入栈,并在必要时增加数组的大小。pop方法从栈中移除顶部元素并返回这个元素,该方法在执行之前会调用 peek方法来确保栈不为空,并获取栈顶元素。

这种简单的栈实现在功能上可能与 java.util.Stack类类似,但它避免了继承自 Vector类的 java.util.Stack带来的线程同步开销。在多线程环境下,我们需要关注线程安全的问题,java.util.Stack是线程同步的,如果不需要这个特性,使用我们自己的 CustomStack会更高效。

如果需要使用链表来手写栈,则可以创建一个节点类来代表链表的节点,然后在栈类中使用这些节点来存储信息。链表实现的栈可以避免数组实现时的数组扩容操作,从而提高操作的效率。

总之,虽然在日常开发中,java.util.Stack正逐渐被其他类如 Deque接口的实现所取代,但手写一个栈(无论是基于数组还是链表)都是一次很好的编程练习,它可以帮助开发者更加深入地理解栈这种数据结构的工作原理和各种操作。

目录
相关文章
|
2月前
|
存储 算法 安全
Java集合框架:理解类型多样性与限制
总之,在 Java 题材中正确地应对多样化与约束条件要求开发人员深入理解面向对象原则、范式编程思想以及JVM工作机理等核心知识点。通过精心设计与周密规划能够有效地利用 Java 高级特征打造出既健壮又灵活易维护系统软件产品。
111 7
|
3月前
|
Java 大数据 API
Java Stream API:现代集合处理与函数式编程
Java Stream API:现代集合处理与函数式编程
270 100
|
3月前
|
Java API 数据处理
Java Stream API:现代集合处理新方式
Java Stream API:现代集合处理新方式
306 101
|
3月前
|
存储 Java Go
对比Java学习Go——函数、集合和OOP
Go语言的函数支持声明与调用,具备多返回值、命名返回值等特性,结合`func`关键字与类型后置语法,使函数定义简洁直观。函数可作为一等公民传递、赋值或作为参数,支持匿名函数与闭包。Go通过组合与接口实现面向对象编程,结构体定义数据,方法定义行为,接口实现多态,体现了Go语言的简洁与高效设计。
|
3月前
|
算法 Java
50道java集合面试题
50道 java 集合面试题
|
4月前
|
存储 NoSQL Java
Java Stream API:集合操作与并行处理
Stream API 是 Java 8 提供的集合处理工具,通过声明式编程简化数据操作。它支持链式调用、延迟执行和并行处理,能够高效实现过滤、转换、聚合等操作,提升代码可读性和性能。
|
4月前
|
存储 缓存 安全
Java集合框架(三):Map体系与ConcurrentHashMap
本文深入解析Java中Map接口体系及其实现类,包括HashMap、ConcurrentHashMap等的工作原理与线程安全机制。内容涵盖哈希冲突解决、扩容策略、并发优化,以及不同Map实现的适用场景,助你掌握高并发编程核心技巧。
|
2月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
198 1
|
2月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
223 1
|
3月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案