4

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.

4

8 回答 8

12

向后循环:

for (int x = saveNames.size()-1; x >= 0; x--)
于 2013-04-30T15:16:45.363 回答
3

需要对现有代码进行少量更改的一种方法是反向遍历向量。

for (int x = saveNames.size() - 1; x >= 0; x--) {
   ...
}
于 2013-04-30T15:17:31.367 回答
2

正如 Fildor 在评论中指出的那样,您可以使用迭代器来做到这一点

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();
    }
}
于 2013-04-30T15:24:02.737 回答
2

当您从中删除项目时,始终在对象中向后循环,因此:

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

这样删除的项目不会给您带来问题。

问题的原因是您从 x=0 开始;你删除了 x=0(所以 x=1 是新的 x=0,x=2 是新的 x=1 等等)但是你继续到 x=1,跳过一个。

另一方面,如果您从 saveNames.size()-1 开始:您从(例如)9 开始,删除它,9 现在是空的,但我们还是继续前进到 8。8 不受影响,因为它在 9 之前

于 2013-04-30T15:17:38.063 回答
0

如果您在循环时从数组中删除项目而遇到麻烦,您可以在循环之前创建一个新数组并将您保留的项目放入其中。循环完成后,新数组将只包含您保留的项目,您可以将原始数组设置为您创建的新数组。

于 2013-04-30T15:16:21.563 回答
0

您可以只添加要删除的索引,然后从最后一个到第一个删除它们。或者你也可以使用

x--;

删除元素时在循环内。

于 2013-04-30T15:17:42.893 回答
0

最简单的做法就是拿出来x++

说明:当您删除saveNames.remove(x)然后x=0索引 1 中的内容移动到索引 0。X 仍然是 0,它现在将删除现在位于索引 0 的第二个项目。一旦所有项目都被删除saveNames.size(),将是 0,x 不是比saveNames.size()所以循环会中断。

于 2017-02-19T15:32:35.753 回答
0

在我看来,通过循环删除项目的最佳和简单方法是:

  1. 使用 for 循环扫描项目并添加 itemsToDelete 列表您要删除的项目。
  2. list.removeAll(itemsToDelete)
于 2015-11-11T13:12:38.317 回答