0

I have a boolean vector with random entries. I mutate it with an invert method. One does it with the traditionally for loop. The other uses foreach.

Why does invert2() not work as invert1()? I thought that b in invert2() is a reference on a boolean element in the vector. Therefore I tried to use Boolean as an object as well. Is b something like vector[i].clone(), where i is a loop variable?

BooleanVector.java

public final class BooleanVector {

    private boolean[] vector;
    private Stack<boolean[]> undoStack = new Stack<>();


    public BooleanVector(final int vectorSize) {
        this.vector = new boolean[vectorSize];
        //Generates random Array for test purposes
        Random random = new Random();
        for (int i = 0; i < vector.length; i++) {
            vector[i] = random.nextBoolean();
        }   
    }

    public void invert1() {
        for (int i = 0; i < this.vector.length; i++) {
            this.vector[i] = !this.vector[i];
        }
    }
    public void invert2() {
        for (Boolean b : vector) {
            b = !b;
        }
    }

    public void printVector() {
        System.out.println(Arrays.toString(this.vector));
    }
}

Main.java

public class Main {
    public static void main(String[] args) {
        BooleanVector vector = new BooleanVector(5);
        vector.printVector();
        System.out.println("Invert1");
        vector.invert1();
        vector.printVector();
        System.out.println("Invert2");
        vector.invert2();
        vector.printVector();
        System.out.println("Invert1");
        vector.invert1();
        vector.printVector();

    }

}

Output:

[true, true, false, true, false]
Invert1
[false, false, true, false, true]
Invert2
[false, false, true, false, true]
Invert1
[true, true, false, true, false]
froehli
  • 904
  • 1
  • 11
  • 35
  • You are just making the `copy`(`b`) of a `reference` to point to a different `object` rather than changing the value of the `object` itself - inside the `forEach` loop. - http://stackoverflow.com/a/40507/1617024 – BatScream Dec 20 '15 at 04:09
  • I also answered to Shubhankar Roy below. I thought that the reference b points to the right boolean object. – froehli Dec 21 '15 at 15:19

1 Answers1

1

In invert1() you are modifying the array values and hence the values are also inverted. Where as in invert2(), you are changing the reference b, and hence is not actually modifying the value in the list.

Roy S
  • 159
  • 7
  • can you give corrected version using the foreach loop, which is similar to my syntax? – froehli Dec 20 '15 at 02:33
  • You won't be able to do it in foreach loop, since Boolean is immutable. If you really need to modify element the list, then you will have to use traditional for loop and set it as `vector.set(i, !vector.get(i));` – Roy S Dec 20 '15 at 02:49
  • What do you mean with "Boolean is immutable". I can assign another boolean value to a boolean after its creation. I am not quite sure what exactly the difference between these two is. `this.vector[1]` should be the same adress as `b` in the first iteration. And it should be also equal. – froehli Dec 21 '15 at 15:18
  • `this.vector[i]` means the i th element of the array and you are simply modifying the i th element of the array in the above code. Where as, in the for each loop, Boolean b is a reference, which points to one of the elements, but when you do `b = !b`, you are telling reference 'b' to point to another object whose value is '!b'. If in your `invert1()` method you did something like this: `Boolean b = this.vector[i]; b=!b;`, in this case you will not be modifying the value of the vector array, but telling the reference to point to a new object whose value is '!b'. You can even try this out. – Roy S Dec 21 '15 at 18:04