Aaron
Aaron

Reputation: 1016

Vector.remove() for loop

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

Answers (8)

user7588908
user7588908

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

john Smith
john Smith

Reputation: 1605

Best and simple way to remove items via loops in my opinion is:

  1. scan the items using for loop and add the itemsToDelete list the items you want to delete.
  2. list.removeAll(itemsToDelete)

Upvotes: 0

Richard Tingle
Richard Tingle

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

Zim-Zam O&#39;Pootertoot
Zim-Zam O&#39;Pootertoot

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

Andy Thomas
Andy Thomas

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

Luis Tellez
Luis Tellez

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

Vincent van der Weele
Vincent van der Weele

Reputation: 13177

Loop backwards:

for (int x = saveNames.size()-1; x >= 0; x--)

Upvotes: 12

shieldgenerator7
shieldgenerator7

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

Related Questions