0

So I have this generic object State which apparently changes its value despite not being edited. Here is what I mean - by invoking the same element in the Queue I am getting different outcomes.

System.out.println(mapString(que.element().getMapState()));
System.out.println(que.element());

The outcome:

the outcome

The second outcome is the correct one.

Missing mapString method just prints the table char[][]:

private static String mapString(char[][] map) {
    String mapString = "";
    for(int k = 0; k<map.length; k++) {
        for(int j = 0; j<map[k].length; j++) {
            mapString += map[k][j];
        }
        mapString += "\n";
    }
    return mapString;
}

While getMapState just returns private variable from the State class

public char[][] getMapState() {
    return map;
}

The Queue is the type of Queue<State> where State is my generic type. I can print it by the toString() method which results in the second (proper) outcome.

public String toString() {
    return "Actual state:\n" + mapString;
}

Where the mapString is a String variable which is initiated in the State class constructor with the same exact String mapString(char[][] map) method.

public State(PlayerAddress player, HashMap<String, BoxAddress> boxList, char[][] map, String solution, String stateHash) {
    this.player = player;
    this.boxList = boxList;
    this.map = map;
    this.solution = solution;
    this.stateHash = stateHash;
    this.boxListString = boxListToString(boxList);
    this.mapString = mapString(map);
}

However, later in the code I am not editing the object in the Queue but nevertheless it edits itself. What could be the reason? I can provide full code if that would change anything.

Lisek
  • 753
  • 2
  • 11
  • 31

2 Answers2

0

Probably we need to see more code. Two points:

  1. Where is the method mapString(char[][] map) declared? Your listing shows it as private static... so presumably it is inside the State class. However, your code:

    System.out.println(mapString(que.element().getMapState())); System.out.println(que.element());

appears to indicate that mapString() is called from outside the State class as if there were a second version?

  1. Try temporarily changing toString() to invoke the mapString() method and retry.

Other than that, please show all the code.


Update: Thanks for the code. Having looked at it, my only idea is that Jorn Vernee was on the right track in his earlier response. Although the constructor in State includes:

this.map = map.clone();

this is only a shallow clone and has little effect as the inner level arrays are not cloned. Could you try a deep clone? i.e. in the constructor:

char[][] newMap = map.clone();
for (int i = 0; i < map.length; i++) {
   newMap[i] = map[i].clone();
}
this.map = newMap;
Grayman
  • 629
  • 4
  • 14
  • Here is the whole code [Main class](http://pastebin.com/7ffZqfyQ) [State class](http://pastebin.com/kRwPDF2E) – Lisek Mar 28 '16 at 18:57
  • 1. I have it in both. In the Main class it is just for debugging. They are both private so it should not be a problem here. Anyways, they do not change the objects, just print them. 2. Not sure what you meant by that. – Lisek Mar 28 '16 at 19:12
0

For some reason if you do this char[][] temp_map = que.element().getMapState() and then later on you edit the temp_map in your code, your first element in the queue changes its value

But honestly, that does not make any sense! Could someone explain that?

Lisek
  • 753
  • 2
  • 11
  • 31
  • 1
    ```temp_map``` is internally a reference, a pointer if you will, to an actual array object in the free store. The thing that is stored in ```que``` is also a pointer. The assignment copies the pointer, but both pointers still point to the same object in the free store. – Jorn Vernee Mar 28 '16 at 19:47