前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java 中的 Vector、Stack 与 ArrayList

Java 中的 Vector、Stack 与 ArrayList

作者头像
Fisherman渔夫
发布2020-02-17 23:41:23
1.1K0
发布2020-02-17 23:41:23
举报
文章被收录于专栏:渔夫渔夫

引子:首先不得不说, Vector 与 Stack 这一对继承设计是蹩脚、失败的。


比如见于 coderanch 的一个问题:

Stack extends Vector !

 The java.util.Stack extends the Vector class. But for Stack, one should be able to insert or retrive the value from only one side i.e at the top of the stack. But since Stack extends Vector, we can use the inherited get(int index) method to access value other than the top of the stack value. It defeats the purpose of Stack, right? Then why does Stack extends Vector. Any explaination ?? Thanks in advance.

 回答是这样的:

 The Stack class represents a last-in-first-out (LIFO) stack of objects. It extends class Vector with five operations that allow a vector to be treated as a stack. The usual push and pop operations are provided, as well as a method to peek at the top item on the stack, a method to test for whether the stack is empty, and a method to search the stack for an item and discover how far it is from the top.

 也就是说,在本质上 Java 中实现的 Stack 就是一个 Vector。上述回答可以用以下代码归纳:

代码语言:javascript
复制
import java.util.Stack;
import java.util.Vector;

public class Test {
    public static void main(String[] args) {
        Vector<String> vector = new Stack<>();
        vector.add("hello");
        vector.add("world");

        //用于证明 Stack 对象也可以使用 Vector 的get(int index)方式得到
        for (int i = 0; i < vector.size(); i++) {
            System.out.println(vector.get(i));
        }
        System.out.println("-----");

        //用于证明可以使用 Stack 对象的peek方法
        Stack stack=(Stack)vector;
        System.out.println(stack.peek());
        System.out.println("-----");

        //用于证明可以使用 Stack 对象的 pop 方法
        while(!stack.empty()){
            System.out.println(stack.pop());
        }

        //用于证明 Stack 对象在元素都弹出后内部元素为0
        System.out.println(vector.size());
        
    }
}

控制台输出:

代码语言:javascript
复制
hello
world
-----
world
-----
world
hello
0

使用 Vector 实现的 Stack 是个好主意吗?

 Vector 其内部是由一个 Object 类型会自动扩容的数组进行存储元素。而 Java 编程思想的作者写到:Stack is inherited from Vector, which says that a Stack is a Vector, which isn’t really true from a logical standpoint. 逻辑上说,栈应该是一个队列。

 除了继承逻辑上的出现的问题,Vector 设计差更体现在效率上。对于 Vector类 以及 Stack类 最大的问题在于对 synchronized 同步关键字的滥用。这个类的公共方法几乎都使用了 synchronized 关键字。这一点你是不会愿意看到的,至少这种确保并发安全的方式太粗粒度了。这两个类作为 Java 的标准类库中的类,这么设计是不合适,因为这可是面对所有 Java 用户的。效率差则体现在:一般而言,在同步锁中我们会进行一系列操作,这是因为获得/释放锁是一项有时间开销的操作。但是如果数据结构是 Vector 或 Stack,那么你的每个单独操作,比如添加一个元素就要进行一次获得/释放锁。如果你需要批量添加元素,那么将有O(n)次的获得以及释放锁,效率极差。而且因为存在类内方法的相互调用,产生了很多没有必要的锁的重载。

 所以说基本上,在大多数情况下,这是一个非常有缺陷的同步方法。Vector 以及 Stack 类本质上可以认为是以下两点结合的产物:

  • 容量大小可变的数组;
  • 每个方法都使用 synchronized 修饰;

 如果你实现打算使用数据结构 Stack ,那么不妨使用 ArrayList 以及 ArrayQueue。

历史原因

 据说,Java 之所以提供这样一个糟糕的类是由于在 Java 发布第一个版本的时候,Java 希望于抢先发布以抢占市场。一些与早期版本捆绑在一起的 Java 类并没有经过深思熟虑。它们并没有经过同行评议和公共审查。例如通过 Java Community Process 、开源项目以及协会项目发布的一些库。Vector 和 Stack 就是属于这些库中的类,并作为一个标准库的蹩脚类存在。再比如 java.util.Date/.Calendar类也是相当蹩脚的存在,Java 为了向后兼容性保存了一部分类,但是不建议在新的代码中使用。

 JavaDoc 也给出了不要使用的建议,以及给出了一个新的方法创建 Stack 对象。

 A more complete and consistent set of LIFO stack operations is provided by the Deque interface and its implementations, which should be used in preference to this class. For example:

Deque<Integer> stack = new ArrayDeque<Integer>();

ArrayList

hierarchy
hierarchy

 至于 ArrayList,其在 JDK 1.2 时加入 Java 标准类库。我们完全可以将其认为是没有进行同步操作的可变大小数组容器。此类的 Java Doc 在第一段写到:

 This class is roughly equivalent to Vector, except that it is unsynchronized.

而 ArrayDeque 中的 JavaDoc 写到:

 This class is likely to be faster than Stack when used as a stack, and faster than LinkedList when used as a queue.

可见一斑。

参考网址:

  • https://stackoverflow.com/questions/1386275/why-is-java-vector-and-stack-class-considered-obsolete-or-deprecated
  • https://stackoverflow.com/questions/37314298/why-stack-extends-vector-in-jdk
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档