IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 【码无巨细】Java Stack类的源码详解 -> 正文阅读

[系统运维]【码无巨细】Java Stack类的源码详解

力扣题

力扣有这么一道题,用两个栈实现队列,做过的小伙伴们应该都知道答案吧,其中栈的实现有两种,一种是Stack<E>,一种是LinkedList<E>接口,那么它们有什么区别呢?

本篇博客深入解析Stack源码,一起来看看吧!

源码

类注释

Stack<E>继承了Vector<E>类,为了实现的逻辑,Stack<E>额外实现了push,pop,peek,empty,search五个方法,这也是最常用的了。

首先,我们需要知道,Vector<E>是一种动态数组,其实现细节不在本篇讨论,只需要知道,它的底层是用数组实现的。

push

push(E item)方法会调用Vector.addElement(E obj)方法,并利用私有add方法实现其逻辑。

大意就是,向底层数组中靠后的位置插入一个元素,如果插入的位置到达了数组长度,就需要调用grow()扩张该数组,然后插入。

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

    return item;
}
public synchronized void addElement(E obj) {
    modCount++;
    add(obj, elementData, elementCount);
}

private void add(E e, Object[] elementData, int s) {
    if (s == elementData.length)
        elementData = grow();
    elementData[s] = e;
    elementCount = s + 1;
}

至于grow()方法,当capacityIncrement > 0时,会将其作为扩容增量,否则,容量将扩至原来的2倍。扩容具体是使用了Arrays.copyOf方法。

privateObject[] grow(int minCapacity) {
    int oldCapacity = elementData.length;
    int newCapacity = ArraysSupport.newLength(oldCapacity,
            minCapacity - oldCapacity, /* minimum growth */
            capacityIncrement > 0 ? capacityIncrement : oldCapacity
                                       /* preferred growth */);
    return elementData = Arrays.copyOf(elementData, newCapacity);
}

pop

pop方法也很简单,调用peek方法,获取要弹出的元素,然后调用Vector.removeElementAt删除size()-1位置的元素。删除元素的时候,要调用System.arraycopy把后续元素向前移动1个位置,即补上缺口。

public synchronized E pop() {
    E       obj;
    int     len = size();

    obj = peek();
    removeElementAt(len - 1);

    return obj;
}
public synchronized void removeElementAt(int index) {
    if (index >= elementCount) {
        throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                 elementCount);
    }
    else if (index < 0) {
        throw new ArrayIndexOutOfBoundsException(index);
    }
    int j = elementCount - index - 1;
    if (j > 0) {
        System.arraycopy(elementData, index + 1, elementData, index, j);
    }
    modCount++;
    elementCount--;
    elementData[elementCount] = null; /* to let gc do its work */
}

peek

这个简单的不能再简单了,看源码吧:

public synchronized E peek() {
    int     len = size();

    if (len == 0)
        throw new EmptyStackException();
    return elementAt(len - 1);
}
public synchronized E elementAt(int index) {
    if (index >= elementCount) {
        throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
    }

    return elementData(index);
}

E elementData(int index) {
    return (E) elementData[index];
}

empty

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

search

search方法是调用了Vector.lastIndexOf,获取对象o在底层数组中出现的最大索引,由于栈是后进先出,所以栈的search方法需要返回的是size()-i,即对象o距离栈顶的最近距离。如果对象在栈中不存在,则返回-1

publicsynchronized int search(Object o) {
    int i = lastIndexOf(o);

    if (i >= 0) {
        return size() - i;
    }
    return -1;
}
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-11-30 16:01:27  更:2021-11-30 16:02:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 2:32:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码