为什么约书亚·布洛赫减少了“的数量?”;“尺寸”;有效java中pop方法中堆栈的值?

为什么约书亚·布洛赫减少了“的数量?”;“尺寸”;有效java中pop方法中堆栈的值?,java,stack,effective-java,Java,Stack,Effective Java,以下是Joshua Bloch编写的《有效java第二版》第2章第24页第6项中的代码。 在他定义的pop方法中,他使用元素[--size]。我想知道为什么他使用--size,而不是元素[size--]应该返回相同的正确值 public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACI

以下是Joshua Bloch编写的《有效java第二版》第2章第24页第6项中的代码。 在他定义的pop方法中,他使用
元素[--size]
。我想知道为什么他使用
--size
,而不是
元素[size--]
应该返回相同的正确值

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);
} }

因为数组是基于0的索引

假设您有一个包含2个元素的堆栈

因此堆栈的大小等于2,在数组中表示为:

elements[0] = elem;
elements[1] = elem;
因此,在从堆栈中弹出元素之前,需要减小大小,否则将尝试弹出不存在的
元素[2]
。所以在这种情况下使用了中缀运算符

return elements[--size];
相当于

size--;
return elements[size];

如果
元素[大小--],它将尝试弹出
元素[2]
,然后将大小减小1。因此,每次要从堆栈中弹出元素时,都会抛出一个
ArrayIndexOutOfBoundsException

简单的答案是,在变量之前迭代之前,减号(或加号)起作用;在变量之后迭代之后,减号(或加号)起作用

例如:

for(x=0; x<3; x++) {
    System.out.print(x);
}
而:

for(x=0; x<3; ++x) {
    System.out.print(x);
}

因为x变量在迭代之前递增

数组使用基于0的索引。看起来有内存泄漏-弹出的元素仍然由堆栈引用。@zhong.j.yu:是的,内存泄漏可以通过引用
元素[size]==null
来修复,
大小+
的相反方向是
--大小
@PeterLawrey没有这样想过,这很有趣。评估后递增与评估前递减是完全互补的。这个问题没有迭代。关键是,++x在求值之前递增,而x++在求值之后递增。这是完全错误的。你以前试过你的代码吗?两者都给出012。@ZouZou这几乎是完美的。“因此,每次要从堆栈中弹出元素时,都会抛出ArrayIndexOutOfBoundsException。”这并不完全正确。假设第一次捕获并处理了异常,下一次大小减量将出现,并且将从此处开始工作,但当仍剩下1个元素时,将抛出空堆栈异常。@Cruncher感谢您的精确性!=)我假设没有捕获异常,并且程序的执行将停止。
for(x=0; x<3; ++x) {
    System.out.print(x);
}
123