Without understanding the way you are setting history, I've made the assumption from your question that you are simply adding the current map to the history list. If you aren't careful, you will be simply adding the same Object, populating the history with multiply Object references to the current map state. This would have the effect you are observing with the state not changing, because you the history only contains a reference to the most recent map (Not storing any actual history).
To obtain the value from an Object, you typically need to clone the object (invoking the clone() method). However, cloning a 2-dimensional array is somewhat problematic. Invoking the clone() method on a 2-dimensional array "shallow" clones the object, essentially only cloning the first dimension while leaving the second as a reference to the same object (The reason for this is that the first 1-dimension of the array holds a reference to the second 1-dimension). Changing the value on a shallow copied object will change the value of the original and vice-versa, not what you want if you want to keep the Objects distinct.
To create two distinct objects, you will need to perform a "deep" clone, which can be easily implemented in a helper method. The below code illustrates the importance of ensuring you fully clone the object before storing it in the history list.
public static void main (String args[]) throws Exception {
ArrayList<String[][]> list = new ArrayList<>();
String[][] shallowClonedMap = new String[1][1];
String[][] deepClonedMap = new String[1][1];
shallowClonedMap[0][0] = "Old";
deepClonedMap[0][0] = "Old";
list.add(shallowClonedMap.clone());
list.add(deepClone(deepClonedMap));
shallowClonedMap[0][0] = "New";
deepClonedMap[0][0] = "New";
list.add(shallowClonedMap.clone());
list.add(deepClone(deepClonedMap));
for (String[][] item : list) {
System.out.print(item[0][0]);
}
}
public static String[][] deepClone(String[][] arry) {
if (arry == null) {
return null;
}
String[][] clone = new String[arry.length][];
for (int i = 0; i < arry.length; i++) {
clone[i] = arry[i].clone();
}
return clone;
}
The output for executing this code is : NewOldNewNew whereas the "intended" output is "OldOldNewNew". From this you can see the shallowClonedMap was updated to "New" even after being cloned and added to the list.