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接口的实现所取代,但手写一个栈(无论是基于数组还是链表)都是一次很好的编程练习,它可以帮助开发者更加深入地理解栈这种数据结构的工作原理和各种操作。

目录
相关文章
|
9天前
|
存储 缓存 安全
Java 集合江湖:底层数据结构的大揭秘!
小米是一位热爱技术分享的程序员,本文详细解析了Java面试中常见的List、Set、Map的区别。不仅介绍了它们的基本特性和实现类,还深入探讨了各自的使用场景和面试技巧,帮助读者更好地理解和应对相关问题。
30 5
|
21天前
|
存储 算法 Java
Java 内存管理与优化:掌控堆与栈,雕琢高效代码
Java内存管理与优化是提升程序性能的关键。掌握堆与栈的运作机制,学习如何有效管理内存资源,雕琢出更加高效的代码,是每个Java开发者必备的技能。
46 5
|
22天前
|
存储 缓存 安全
Java 集合框架优化:从基础到高级应用
《Java集合框架优化:从基础到高级应用》深入解析Java集合框架的核心原理与优化技巧,涵盖列表、集合、映射等常用数据结构,结合实际案例,指导开发者高效使用和优化Java集合。
33 4
|
1月前
|
Java
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
30 2
|
1月前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
1月前
|
存储 Java 开发者
在 Java 中,如何遍历一个 Set 集合?
【10月更文挑战第30天】开发者可以根据具体的需求和代码风格选择合适的遍历方式。增强for循环简洁直观,适用于大多数简单的遍历场景;迭代器则更加灵活,可在遍历过程中进行更多复杂的操作;而Lambda表达式和`forEach`方法则提供了一种更简洁的函数式编程风格的遍历方式。
|
1月前
|
存储 Java 开发者
Java中的集合框架深入解析
【10月更文挑战第32天】本文旨在为读者揭开Java集合框架的神秘面纱,通过深入浅出的方式介绍其内部结构与运作机制。我们将从集合框架的设计哲学出发,探讨其如何影响我们的编程实践,并配以代码示例,展示如何在真实场景中应用这些知识。无论你是Java新手还是资深开发者,这篇文章都将为你提供新的视角和实用技巧。
32 0
|
Java 安全
java Stack源码解析
本源码解析基于JDK1.7 概要 Stack是基于Vector实现的first-in-last-out数据结构 Stack用同步来实现了线程安全,因此在单线程情况下该类会由于加锁开销而效率低 Stack在Vecto...
956 1
|
7天前
|
安全 Java API
java如何请求接口然后终止某个线程
通过本文的介绍,您应该能够理解如何在Java中请求接口并根据返回结果终止某个线程。合理使用标志位或 `interrupt`方法可以确保线程的安全终止,而处理好网络请求中的各种异常情况,可以提高程序的稳定性和可靠性。
37 6
|
22天前
|
设计模式 Java 开发者
Java多线程编程的陷阱与解决方案####
本文深入探讨了Java多线程编程中常见的问题及其解决策略。通过分析竞态条件、死锁、活锁等典型场景,并结合代码示例和实用技巧,帮助开发者有效避免这些陷阱,提升并发程序的稳定性和性能。 ####
下一篇
DataWorks