为啥 Stack 使用基于 1 的索引而不是 Java 中的 Array 中的基于 0 的索引?

Posted

技术标签:

【中文标题】为啥 Stack 使用基于 1 的索引而不是 Java 中的 Array 中的基于 0 的索引?【英文标题】:Why Stack uses 1-based index and not 0-based as in Array in Java?为什么 Stack 使用基于 1 的索引而不是 Java 中的 Array 中的基于 0 的索引? 【发布时间】:2020-05-12 02:00:14 【问题描述】:

为什么 Java 中的 Stack 实现从堆栈顶部返回对象所在的方法 search(Object) 的从 1 开始的位置,而不是像我们通常在 Array 中那样从 0 开始的位置。这是否有任何特殊原因,或者如果我们使用基于 0 的索引,如果没有解决,这是否解决了任何特定问题?

【问题讨论】:

是的,正是.. Stack 类中的 search(Obj) 方法 我只是在猜测,但我的猜测是它描述了您必须调用多少次 pop 才能获取对象。 Stack 是 JDK 1.0 中的类之一,API 文档说应该使用 Deque。原来的 API 有它的缺点,很多类都非常接近相关的 C 库。很可能他们只是碰巧使用了 1,一旦 API 发布,更改它就太迟了。 【参考方案1】:

你可以在docs看到

...此方法返回距离栈顶最近的事件的栈顶距离;堆栈上最顶部的项目被认为在距离 1...

该方法从堆栈大小中从Vector 基类中减去基于0 的lastIndexOf()

来自source code

public synchronized int search(Object o) 
    int i = lastIndexOf(o);

    if (i >= 0) 
        return size() - i;
    
    return -1;

如果堆栈中有一个元素,比如“A”,它将是最顶部的元素,因此与顶部的距离将为 1。size() - lastIndexOf("A") == 1

【讨论】:

【参考方案2】:

Stack.search 返回的 position 是从数据结构的末尾开始的,而 indexes 是从开始的。范围通常指定为半开区间,因此第一个元素与边界的距离不为零是有意义的。类似的方法List.lastIndexOf 从列表的开头给出一个值。 searchlastIndexOf 返回的值的总和是size

@TJCrowder 还指出search 位置与您需要执行的pops 的数量相匹配才能获得该元素。

请注意 API 文档状态:

一组更完整和一致的 LIFO 堆栈操作是 由 Deque 接口及其实现提供,应该 优先使用此类。

编辑:有趣的是,它继续建议此代码(无需费心链接 Deque 类型):

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

由于决策失误,DequeQueue。所以你可以但不应该写:

Queue<Integer> doNotDoThisFFS = new ArrayDeque<Integer>();

写“Stack&lt;Integer&gt; stack();”的正确咒语是:

Queue<Integer> stack = Collections.asLifoQueue​(new ArrayDeque<Integer>());

【讨论】:

以上是关于为啥 Stack 使用基于 1 的索引而不是 Java 中的 Array 中的基于 0 的索引?的主要内容,如果未能解决你的问题,请参考以下文章

为啥要使用 Deque 而不是内置 Stack<>? [复制]

为啥 java.util.Stack 是使用 Vector 而不是 Arraylist 实现的

为啥这个查询使用 where 而不是索引?

为啥 Postgresql 使用过滤器而不是索引?

mysql 为啥总是推荐使用联合索引而不是单值索引

为啥当 WHERE 子句包含参数化值时 SQL Server 使用索引扫描而不是索引查找