这就是我正在讨论的代码:
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)。
发布于 2020-10-17 04:14:32
我将其解释为对假想的未来bug的安心防御。确实,正如所写的那样,这个类的数组容量不是0,因此添加1并不是严格必要的,但是一旦添加了更多的特性,这个假设可能就会悄悄地失败。
可能的附加特性的示例包括来自java.util.ArrayList的那些特性,它有一个可以将容量设置为0的trimToSize()方法,一个允许从(可能为空的)集合初始化数据的构造函数,以及一个允许将容量显式设置为0的构造函数。您还可以想象这样一种特性,当该类被清空时,它会自动减少该类的分配容量。或者,也许有人会编辑DEFAULT_INITIAL_CAPACITY常量。现在想象一下,容量改变的方法被javadoc注释的屏幕分隔开,并在子类之间拆分。很容易忘记你应该防止容量变为0。
如果ensureCapacity()依赖于大小为非零的值,则在修改类时必须始终牢记这一假设。添加+1是一种低成本的更改,可以消除这种担忧。这也是一个处理边缘情况的简单算术方法的示例。
发布于 2020-10-17 09:09:38
对我来说,这似乎比@Boann使用的所有措辞更明显,尽管他/她的答案中确实有更简单的答案。答案很简单,作者希望支持在设置DEFAULT_INITIAL_CAPACITY = 0的zero...of大小上启动数组。这将导致代码在没有+1的情况下崩溃。没有其他方法可以使elements数组的大小为零,除非它以这种方式开始,这是产生+1的唯一原因。
因为代码已经写好了,所以没有理由使用+1。
https://stackoverflow.com/questions/64394410
复制相似问题