首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Joshua Bloch在Effective Java中使用2*size +1来调整堆栈的大小?

为什么Joshua Bloch在Effective Java中使用2*size +1来调整堆栈的大小?
EN

Stack Overflow用户
提问于 2020-10-17 02:17:24
回答 2查看 325关注 0票数 12

这就是我正在讨论的代码:

代码语言:javascript
复制
public class Stack {
  private Object[] elements;
  private int size = 0;
  private static final int DEFAULT_INITIAL_CAPACITY = 16;
  public Stack() {
    elements = new Object[DEFAULT_INITIAL_CAPACITY];
  }
  public void push(Object e) {
    ensureCapacity();
    elements[size++] = e;
  }
  public Object pop() {
    if (size == 0)
      throw new EmptyStackException();
    return elements[--size];
  }
  /**
   * Ensure space for at least one more element, roughly
   * doubling the capacity each time the array needs to grow.
   */
  private void ensureCapacity() {
    if (elements.length == size)
      elements = Arrays.copyOf(elements, 2 * size + 1);
  }
}

为什么不简单地将最后一行保留为elements = Arrays.copyOf(elements, 2 * size);

它可能有效的唯一情况是Stack的初始大小为0。但在本例中,它是一个常量- DEFAULT_INITIAL_CAPACITY (一个非零值)。并且没有其他重载构造函数可以从user获取此值(或将其默认为0)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-10-17 04:14:32

我将其解释为对假想的未来bug的安心防御。确实,正如所写的那样,这个类的数组容量不是0,因此添加1并不是严格必要的,但是一旦添加了更多的特性,这个假设可能就会悄悄地失败。

可能的附加特性的示例包括来自java.util.ArrayList的那些特性,它有一个可以将容量设置为0的trimToSize()方法,一个允许从(可能为空的)集合初始化数据的构造函数,以及一个允许将容量显式设置为0的构造函数。您还可以想象这样一种特性,当该类被清空时,它会自动减少该类的分配容量。或者,也许有人会编辑DEFAULT_INITIAL_CAPACITY常量。现在想象一下,容量改变的方法被javadoc注释的屏幕分隔开,并在子类之间拆分。很容易忘记你应该防止容量变为0。

如果ensureCapacity()依赖于大小为非零的值,则在修改类时必须始终牢记这一假设。添加+1是一种低成本的更改,可以消除这种担忧。这也是一个处理边缘情况的简单算术方法的示例。

票数 13
EN

Stack Overflow用户

发布于 2020-10-17 09:09:38

对我来说,这似乎比@Boann使用的所有措辞更明显,尽管他/她的答案中确实有更简单的答案。答案很简单,作者希望支持在设置DEFAULT_INITIAL_CAPACITY = 0的zero...of大小上启动数组。这将导致代码在没有+1的情况下崩溃。没有其他方法可以使elements数组的大小为零,除非它以这种方式开始,这是产生+1的唯一原因。

因为代码已经写好了,所以没有理由使用+1

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64394410

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档