java集合系列(7)Stack

简介: 这篇文章开始介绍Stack。从名字看他就是一个stack,因此具有数据结构中栈的一般特性(后进先出),平时用起来相对较多一点,但是也是非常简单。这篇文章我们将从源码的角度来分析一下Stack。

一、认识Stack


Stack继承自Vector。底层是通过数组实现的。下面我们认识一下Stack在整个java集合体系中的位置:

v2-09045bf074eb638b76e271ec1095b176_1440w.jpg我们会发现,其实Stack就是继承自Vector,因此它具有Vector的一般特点。我们把Stack放大,从Stack的角度来看一下:

v2-9b9857dce40448ec102d570a87daae6a_1440w.jpg

从上图我们可以看到,Stack其实就是继承了Vector,Vector具有的接口的父类,Stack也有。


继承了AbstractList、实现了Enumeration、List、ListIterator等接口。

下面我们再来看一下源码,它的源码那是超级简单。


二、源码分析


一下源码基于jdk1.8来分析的。


(1)构造方法

public Stack() {}

只有一个无参构造方法。

(2)增加元素

public E push(E item) {
        addElement(item);
        return item;
}

这里面调用了addElement方法,我们追踪进去,继续往里看

public synchronized void addElement(E paramE) {
    this.modCount += 1;
    ensureCapacityHelper(this.elementCount + 1);
    this.elementData[(this.elementCount++)] = paramE;
}

synchronized 说明了这是一个线程安全的方法,他分了三步走的战略:


  • 第一步:它在添加元素的时候首先将modCount加1,保证线程安全。
  • 第二步:ensureCapacityHelper()主要用于保障Stack的容量,在合理范围
  • 第三步:真正实现元素的添加,将该元素添加到栈顶,数目加1;

(3)删除元素

public synchronized E pop() {
    E  obj;
    int  len = size();
    obj = peek();
    removeElementAt(len - 1);
    return obj;
}

在这里我们发现,真正实现删除操作的是removeElementAt;我们追踪进去:

public synchronized void removeElementAt(int paramInt) {
    this.modCount += 1;
    if (paramInt >= this.elementCount)
      throw new ArrayIndexOutOfBoundsException(paramInt + " >= "
          + this.elementCount);
    if (paramInt < 0)
      throw new ArrayIndexOutOfBoundsException(paramInt);
    int i = this.elementCount - paramInt - 1;
    if (i > 0)
      System.arraycopy(this.elementData, paramInt + 1, this.elementData,
          paramInt, i);
    this.elementCount -= 1;
    this.elementData[this.elementCount] = null;
}

synchronized 说明了这是一个线程安全的方法,删除操作就有点复杂了,没关系我们继续分析:


  • 第一步:它在添加元素的时候首先将modCount加1,保证线程安全。
  • 第二步:第一个if判断删除元素是否超出了存储的数量范围
  • 第三步:第二个if判断待删除的元素下标大于0
  • 第四步:第三个if将元素后移
  • 第五步:将数量减小1
  • 第六步:将最上面的元素置为空,也就是删除了元素。

(4)查找操作

在上面删除的时候我们发现了其实有一个peek()方法我们没有将,他的作用就是返回stack中最顶端的元素。

public synchronized E peek() {
        int  len = size();
        if (len == 0)
            throw new EmptyStackException();
        return elementAt(len - 1);
}

但是还有一个最正式的查找操作:

public synchronized int search(Object o) {
        int i = lastIndexOf(o);
        if (i >= 0) {
            return size() - i;
        }
        return -1;
}

该方法返回所查找对象所处的位置,如果不存在在返回-1;


  • 第一步:通过lastLindexOf(Object)方法返回从栈底到栈顶最下面的的那个元素的下标,
  • 第二步:利用元素的总数目减去所处的下标就得到了元素的位置(),并且返回否则返回-1;


(5)其他方法

这里提供的其他方法只有一个判断是否为空

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

以上就列出了Stack的所有源码,超级简单。最后我们就来对它进行有一个总结


三、总结


stack是继承自Vector,底层使用数组存储、用来模拟栈的一个java集合。同时也是线程安全的。使用场景比如说倒序输出、XML语法检查。最主要的是面试还经常使用到它,因此你主要还是在机试的时候灵活的去使用它。

相关文章
|
12天前
|
存储 缓存 安全
Java 集合框架优化:从基础到高级应用
《Java集合框架优化:从基础到高级应用》深入解析Java集合框架的核心原理与优化技巧,涵盖列表、集合、映射等常用数据结构,结合实际案例,指导开发者高效使用和优化Java集合。
25 3
|
27天前
|
Java
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
27 2
|
1月前
|
存储 Java
判断一个元素是否在 Java 中的 Set 集合中
【10月更文挑战第30天】使用`contains()`方法可以方便快捷地判断一个元素是否在Java中的`Set`集合中,但对于自定义对象,需要注意重写`equals()`方法以确保正确的判断结果,同时根据具体的性能需求选择合适的`Set`实现类。
|
27天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
1月前
|
存储 Java 开发者
在 Java 中,如何遍历一个 Set 集合?
【10月更文挑战第30天】开发者可以根据具体的需求和代码风格选择合适的遍历方式。增强for循环简洁直观,适用于大多数简单的遍历场景;迭代器则更加灵活,可在遍历过程中进行更多复杂的操作;而Lambda表达式和`forEach`方法则提供了一种更简洁的函数式编程风格的遍历方式。
|
1月前
|
Java 开发者
|
2月前
|
安全 Java 程序员
深入Java集合框架:解密List的Fail-Fast与Fail-Safe机制
本文介绍了 Java 中 List 的遍历和删除操作,重点讨论了快速失败(fail-fast)和安全失败(fail-safe)机制。通过普通 for 循环、迭代器和 foreach 循环的对比,详细解释了各种方法的优缺点及适用场景,特别是在多线程环境下的表现。最后推荐了适合高并发场景的 fail-safe 容器,如 CopyOnWriteArrayList 和 ConcurrentHashMap。
60 5
|
1月前
|
存储 算法 Java
🧠Java零基础 - Java栈(Stack)详解
【10月更文挑战第17天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
28 2
|
2月前
|
安全 Java 程序员
Java集合之战:ArrayList vs LinkedList,谁才是你的最佳选择?
本文介绍了 Java 中常用的两个集合类 ArrayList 和 LinkedList,分析了它们的底层实现、特点及适用场景。ArrayList 基于数组,适合频繁查询;LinkedList 基于链表,适合频繁增删。文章还讨论了如何实现线程安全,推荐使用 CopyOnWriteArrayList 来提升性能。希望帮助读者选择合适的数据结构,写出更高效的代码。
71 3
|
1月前
|
存储 Java 开发者
Java中的集合框架深入解析
【10月更文挑战第32天】本文旨在为读者揭开Java集合框架的神秘面纱,通过深入浅出的方式介绍其内部结构与运作机制。我们将从集合框架的设计哲学出发,探讨其如何影响我们的编程实践,并配以代码示例,展示如何在真实场景中应用这些知识。无论你是Java新手还是资深开发者,这篇文章都将为你提供新的视角和实用技巧。
28 0