Reputation: 1016
I am programming a game and almost have the save-file system complete. I have two Vectors (one holds the name of the savegame, one holds the sessionID).
At launch, the program will read in data from a file and add that information to the Vectors. Then another method is called to check if the files shown in the Vector acctualy exist. If not, they will be removed from the Vectors. At the end, the Vectors are printed to and rewrite the file.
The problem I'm having is the for loop isn't checking every item in the Vector, because Vector.size() is decreasing when items are removed.Is there a better way to form the for loop, or is there a workaround I can use?
private static void slistCleanup() throws IOException {
private static Vector<String> saveNames = new Vector<String>();
private static Vector<Integer> sessionIDs = new Vector<Integer>();
Scanner slistReader = new Scanner(new FileReader(sessionList));
File tempSave;
String path;
int run = 1;
String tempName = " ";
int tempID = 0;
for (int x = 0; x < saveNames.size(); x++) {
path = currentDir + "\\saves\\" + sessionIDs.elementAt(x) + ".sav";
tempSave = new File(path);
System.out.println("-----------------------"); //debug
System.out.println("current pass: " + run);
System.out.println("tempSave Path: " + tempSave.getAbsolutePath()); //debug
System.out.println("tempSave exists: " + tempSave.exists()); //debug
System.out.println("-----------------------"); //debug
run++; //debug
if (!tempSave.exists()) {
saveNames.remove(x);
sessionIDs.remove(x);
}
}
for (int x = 0; x < saveNames.size(); x++) {
System.out.println(saveNames.elementAt(x));
System.out.println(sessionIDs.elementAt(x));
}
slistReader.close();
}
If you need more code, let me know.
Upvotes: 4
Views: 5377
Reputation:
The simplest thing to do is just take out x++
.
Explanation: When you remove saveNames.remove(x)
and x=0
then what was in index 1 moves to index 0. X is still 0 and it'll now remove the 2nd item which is now at index 0. Once all the items are removed saveNames.size()
will be 0, x is no longer less than saveNames.size()
so the loop will break.
Upvotes: 0
Reputation: 1605
Best and simple way to remove items via loops in my opinion is:
Upvotes: 0
Reputation: 17226
Always loop backwards through an object when you are removing items from it, so:
for (int x = saveNames.size()-1; x >=0; x--) {
That way the removed items don't cause you a problem.
The reason for the problem is that you are starting at x=0; you delete x=0 (so x=1 is the new x=0, x=2 is the new x=1 etc) but you move on to x=1, skipping one.
On the other hand if you start at saveNames.size()-1: You start at (for example) 9, delete it, 9 is now empty but we move on to 8 anyway. 8 is unaffected because its before 9
Upvotes: 2
Reputation: 18148
As Fildor noted in the comments, you can do this with iterators
Iterator namesItr = saveNames.iterator();
Iterator sessionItr = sessionIDs.iterator();
while(namesItr.hasNext() && sessionItr.hasNext()) {
Object currentName = namesItr.next();
Object currentSession = sessionItr.next();
if (!tempSave.exists()) {
namesItr.remove();
sessionItr.remove();
}
}
Upvotes: 2
Reputation: 86391
One way that would require few changes to your existing code would be to traverse the vector in the reverse direction.
for (int x = saveNames.size() - 1; x >= 0; x--) {
...
}
Upvotes: 3
Reputation: 2973
You can just add the indexes you want to remove, and the going from last to first remove them. Or you can also use
x--;
inside your loop when you remove a element.
Upvotes: 0
Reputation: 13177
Loop backwards:
for (int x = saveNames.size()-1; x >= 0; x--)
Upvotes: 12
Reputation: 1736
If you are having trouble because you're deleting items from the array as your looping over it, you can make a new array before the loop and put items you're keeping into it. After the loop is done, the new array will only contain items you're keeping, and you can set the original array to the new array you created.
Upvotes: 0