> Java, why isn't this ArrayList saving the arrays I enter the way I want?

Java, why isn't this ArrayList saving the arrays I enter the way I want?

Posted at: 2014-12-18 
Arrays are objects, passed by reference, so unless you are creating a new array for each all to loopCheck(), you'll get duplicate references in your array list.

One way to avoid that is to "clone" the states array. Make a "deep copy" of the array and add that to the ArrayList instead of the argument. I'd make another method for this in case it's needed in more than one place:

public static int[][] copyStates(int[][] states) {

.... int[][] result = new int[state.length][];

.... for (int i=0; i
.... .... result[i] = Arrays.copyOf( states[i], states[i].length );

.... }

}

Something like that will do a deep copy of the array. You already have java.util.Arrays imported.

Then, just copyStates(states) to the ArrayList, not states itself.

An unrelated note: ArrayList is much better at adding to the end of the array rather than the beginning. You're better off adding to the end and reversing the index values in your search loop:

int nstates = statesLoopCheck.size(); // after add() call

for (int u=n-2; u>=0; --u) {

...

}

Then print out (n-1-u) instead of u when a loop is found, if you need the message to count backward in "time" from the most recent state.

import java.util.*;

public class Program {

public static void main(String[] args) {

List< Integer[][]> states = new ArrayList< Integer[][]>(0);

Integer[][] head = buildItem(5, 5, 1);

states.add(head);

Integer[][] tail = buildItem(5, 5, 2);

states.add(tail);

Integer[][] tail2 = buildItem(5, 5, 3);

states.add(tail2);

int found = check(states);

if (found > 0) {

System.out.format("Loop detected. Duration of loop: %d%n", found);

}

}

private static int check(List states) {

int result = 0;

// always comparing with the first element...

for (int i = 1; i < states.size(); i++) {

if (Arrays.deepEquals( states.get(0), states.get(i))) {

result = i;

break;

}

}

return result;

}

private static Integer[][] buildItem(int r, int c, int value) {

Integer[][] results = new Integer[r][c];

for (int row = 0; row < r; row++) {

for(int col = 0; col < c; col++) {

results[row][col] = value;

}

}

return results;

}

}

Your code looks quite convoluted and (I'm sorry to say) you haven't clearly explained what you want to do. However, I do spot one possible problem, which concerns the difference between values and references.

If we look at this method heading:

private static int loopCheck(Integer[][] states, ArrayList statesLoopCheck)

The parameter named "states" is a reference (pointer) to a 2-D array structure. When you put this into the array list, then it is the *pointer* that gets saved, not the actual values referenced by the pointer.

If you're going to call this method again, then you need to discard the variable that you passed as states, and use "new" to create a new array with a new (and therefore different pointer). You can then populate this new array with your data and save it in the Array List.

The temptation is to re-use the original 2-D array and re-populate it with the new data which you then put into the Array List. Of course, when you think about it, this means that any previous data gets lost, because the Array List just contains multiple entries, all of which point to the *same* 2-D array, instead of lots of different pointers, each pointing to a different 2-D array.

I'm not sure if this sheds any light on your problem!

They're not the same

I've got a 2D array in java that updates every second, but I want to check if at some point it loops. The way I tried to do this is by storing the array every time it updates in a ArrayList and checking if any of them is the same as the first one. The code I use for this is:

ArrayList statesLoopCheck = new ArrayList<>();

private static int loopCheck(Integer[][] states, ArrayList statesLoopCheck) {

statesLoopCheck.add(0, states);

for(int u = 1; u
if(Arrays.deepEquals(statesLoopCheck.get(u), states)) {

System.out.println("Loop detected. Duration of loop: "+u+" steps.");

return u;

}

}

return 0;

}

and somewhere else I delete the 5th entry of statesLoopCheck.

The problem is that instead of saving the array as it is at that point, it 'updates' along with states. So every time it checks, all the arrays saved in statesLoopCheck are the same so it just says there is a loop in 1 step.

What I need is that the arrays keep their actual values.

Thanks in advance!