在从文件中读取和删除某些行时遇到问题? [英] Having problems reading from and deleting certain lines from a file?

查看:123
本文介绍了在从文件中读取和删除某些行时遇到问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此计划的目的是从文本文件中删除某些运动队及其成员,然后使用新的值集覆盖原始文件。这是通过将值读入数组,然后循环遍历数组并删除团队名称和接下来的2行来尝试的,但由于某种原因,它会在索引之后停止通过数组。

The point of this program is to remove certain sports teams and their members from a text file, then overwrite the original file with the new set of values. This is attempted by reading the values into an array, then looping through the array and deleting the name of the team and the next 2 lines but for some reason it stops going through the array after the index.

我被困了,所以任何帮助都会很棒

I'm stuck, so any help would be great

代码:

private void RemoveSportsTeamButtonActionPerformed(java.awt.event.ActionEvent evt) {

    String ChosenTeam = "";
    ChosenTeam = JOptionPane.showInputDialog("What Team Do you want to remove?");

    ArrayList<String> Teamlist = new ArrayList<String>();

    if (ChosenTeam.length() > 0) {
    } else {
        Scanner Reader = null;
        try {
            Reader = new Scanner(new File("ListofSportTeams.txt"));
        } catch (FileNotFoundException ex) {

        }

        while (Reader.hasNext()) {
            Teamlist.add(Reader.next());
        }
        Reader.close();

        for (int count = 0; count < Teamlist.size(); count++) {
            {
                if (Teamlist.get(count).equals(ChosenTeam)) {
                    Teamlist.remove(count);
                    Teamlist.remove(count + 1);
                    Teamlist.remove(count + 2);
                }
            }

        }
    }

}

SportTeamList.txt =

SportTeamList.txt =

Team1
Jeff
James
Team2
Steve
Peter


推荐答案

迭代时,从不 列表中删除​​。你正在做什么。

You should never remove from a List when iterating. Which you are doing.

考虑一个简单的例子,我有一个列表 {1,2,3,4,5} 。让我们假设其0索引,我想删除大于3的所有数字。

Consider a trivial example, I have a list {1,2,3,4,5}. Let us assume its 0-indexed and I want to remove all numbers greater than 3.

0 - 列表项是 1 ,keep

1 - 列表项是 2 ,保持

2 - 列表项是 3 ,删除。所有元素都被移位,列表现在是 {1,2,4,5}

3 - 列表项是 5 ,删除

4 - 列表商品是 oops,不再是4

0 - List item is 1, keep
1 - List item is 2, keep
2 - List item is 3, remove. All elements get shifted, list is now {1,2,4,5}.
3 - List item is 5, remove
4 - List item is oops, there is no longer a 4

所以我超过了 List 的结尾,因为当我开始迭代时,我把大小设为 5 但它我在索引 2 中删除​​元素后变为 4 ,它变为 3 当我在索引 3 中删除​​元素时。

So I have overshot the end of the List because I took the size to be 5 when I started iterating but it became 4 after I removed the element at index 2 and it became 3 when I removed the element at index 3.

你可能会说,啊哈,我可以使用修复此问题,而循环:

You might say, "Ah ha, I can fix this with a while loop":

int i = 1;
while(i < teams.size()) {
    //do stuff
}

更差

0 - 列表项 1 ,保持

1 - 列表项是 2 ,保持

2 - 列表项是 3 ,删除。所有元素都被移位,列表现在是 {1,2,4,5}

3 - 列表项是 5 ,删除

0 - List item is 1, keep
1 - List item is 2, keep
2 - List item is 3, remove. All elements get shifted, list is now {1,2,4,5}.
3 - List item is 5, remove

所以,没有错误。看起来问题已修复。但是这个清单包含什么?它包含 {1,2,4} 。但 4 大于 3 。由于指数转移,它被跳过了。你现在有一个更加阴险的错误。

So, no error. Looks like the issue is fixed. But what does the list contain? It contains {1,2,4}. But 4 is greater than 3. It was skipped due to the index shift. You now have an even more insidious bug.

如果你使用了正确的增强型foreach循环:

If you were using a proper enhanced foreach loop like so:

for(final String team : teams) {
    //do stuff with team
}

您可以正确获得 ConcurrentModificationException 。这只是使用增强型foreach循环而不是按索引循环的众多原因之一。

You would have, correctly, gotten a ConcurrentModificationException. This is just one of many reasons to use the enhanced foreach loop rather than looping by index.

为了做你想做的事情,使用迭代器

In order to do what you want use an Iterator:

final Iterator<String> iter = teams.iterator();
while(iter.hasNext()) {
    if(iter.next().equals(testString))
        iter.remove();
}

我将重申我的评论:

始终使用 Java命名约定。变量应始终位于 camelCase 中。 PascalCase 是为班级保留的。

Please always use Java naming conventions. Variables should always be in camelCase. PascalCase is reserved for classes.

更新

可能更容易使用 indexOf 方法在列表中查找团队名称并删除所需的元素

It might be easier so use the indexOf method to find the team name in the List and remove the required elements

public void remove(final List<String> teams, final String name) {
    final int idx = teams.indexOf(name);
    if(idx < 0) 
        throw new IllegalArgumentException("Team " + name + " not present in list.");
    for(int i = idx + 2; i >= idx; --i) 
        teams.remove(i);
}

删除项目非常重要 即可。这是由于与上述相同的问题,如果您删除索引处的项目(例如) 10 ,那么索引为 11的项目向下移动。所以当你去索引 11 的项目时,你实际上是删除了最初的索引项目 12

It is very important to remove the items in reverse. This is due to the same problem as above, if you remove the item at index (for example) 10 then the item that was at index 11 is moved down. So when you go to remove the item at index 11 you are actually removing the item what initially was it index 12.

您可以使用脏技巧

for(int i = 0; i < 2; ++i)
    teams.remove(idx) 

即继续删除找到的索引处的项目,因为列表将向下移动以填补您将实际删除所需项目和其上方的两个项目的差距。我认为这使得代码很难阅读。您可能会忘记这个技巧然后回到代码中并且必须弄清楚它正在做什么。

I.e. keep removing the item at the found index, as the list will shuffle downwards to fill the gap you will actually remove the required item and the two that were above it. I think this makes code very hard to read. You will probably forget this trick and then come back to the code and have to work out what it is doing.

这篇关于在从文件中读取和删除某些行时遇到问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆