3

here is the code from Item 6, pg 24, chapter 2 of effective java 2nd edition, by Joshua Bloch. In the pop method he defines, he uses elements[--size]. I am wondering why he used --size, instead elements[size--] should return the same correct?

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);
} }
Machavity
  • 30,841
  • 27
  • 92
  • 100
brain storm
  • 30,124
  • 69
  • 225
  • 393
  • 1
    Arrays uses 0-based indices. – Sotirios Delimanolis Sep 27 '13 at 18:41
  • 3
    looks like there's a memory leak - the popped element is still referenced by stack. – ZhongYu Sep 27 '13 at 18:42
  • @zhong.j.yu: yes, the memory leak could be fixed by referencing the `elements[size]==null` – brain storm Sep 27 '13 at 18:43
  • 3
    The reverse of `size++` is `--size` – Peter Lawrey Sep 27 '13 at 18:49
  • 1
    @PeterLawrey Hadn't really thought about it like that, that's interesting. Incrementing after evaluation, is completely complimentary to decrementing before evaluation – Cruncher Sep 27 '13 at 19:00
  • @Cruncher similar is a write barrier after a write and a read barrier before a read. – Peter Lawrey Sep 27 '13 at 19:35
  • @brainstorm I think it'd need to be `Object o = elements[--size]; elements[size] = null; return o;` – Phil Wright Nov 19 '14 at 12:17
  • 1
    For those pointing out the memory leak: Although brain storm doesn't mention it, Joshua Bloch's full title for this section is "Item 6: Eliminate obsolete object references", and the first paragraph following the example is "There is nothing obviously wrong with this program [...] it would pass every test with flying colors, but there's a problem lurking. Loosely speaking, the program has a 'memory leak', [...]". It's intentional. – Kevin J. Chase Mar 23 '15 at 21:57

2 Answers2

11

Because arrays are 0 based indexed.

Imagine that you have a stack with 2 elements.

So the size of the stack is equals to 2 with the following representation in the array :

elements[0] = elem;
elements[1] = elem;

So you need to decrease size before pop the elem from the stack, otherwise you will try to pop elements[2], which doesn't exists. So an infix operator is used in this case.

return elements[--size];

is equivalent to

size--;
return elements[size];

If elements[size--]; was written, it would try to pop elements[2] and then decrease size by 1. So an ArrayIndexOutOfBoundsException will be thrown each time you want to pop an element from the stack.

Alexis C.
  • 91,686
  • 21
  • 171
  • 177
  • @ZouZou this is almost perfect. "So an ArrayIndexOutOfBoundsException will be thrown each time you want to pop an element from the stack." This is not entirely correct. Assuming the exception is caught and handled the first time, the next time around the size decrement will be there, and it will work from here, but throw an empty stack exception when there is still 1 element left. – Cruncher Sep 27 '13 at 18:55
  • @Cruncher Thanks for the precisions ! =) I assumed that the exception is not caught and the execution of the program will be stopped. – Alexis C. Sep 27 '13 at 19:06
-1

The simple answer is the minus-minus (or plus plus) acts before iterating when it comes before the variable and after iterating when it comes after the variable.

For example:

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

returns:

012

While:

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

returns:

123

because the x variable is incremented before the iteration.