为什么约书亚·布洛赫减少了“的数量?”;“尺寸”;有效java中pop方法中堆栈的值?
以下是Joshua Bloch编写的《有效java第二版》第2章第24页第6项中的代码。 在他定义的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
元素[--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];
如果
元素[大小--]如果编写了code>,它将尝试弹出元素[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