2014-02-08 4 views
0

Цель этой программы - удалить определенные спортивные команды и их членов из текстового файла, а затем перезаписать исходный файл новым набором значений. Это делается путем считывания значений в массив, затем цикла через массив и удаления имени команды и следующих двух строк, но по какой-то причине она перестает проходить через массив после индекса.Проблемы с чтением и удалением определенных строк из файла?

я застрял, так что любая помощь будет большим

Код:

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 =

Team1 
Jeff 
James 
Team2 
Steve 
Peter 
+2

Пожалуйста ** всегда ** использовать Java именования. Переменные должны ** всегда ** находиться в 'camelCase'. 'PascalCase' зарезервирован для классов. Этот код неразборчив, я должен сконцентрироваться, чтобы даже разобраться в том, что такое 'class' и что такое переменная. Правильно отредактируйте свой код. И отформатируйте его. –

ответ

2

Вы должны никогдаremove из List при переборе , Что вы делаете.

Рассмотрите тривиальный пример, у меня есть список {1,2,3,4,5}. Допустим, его 0-проиндексированы, и я хочу, чтобы удалить все числа больше 3.

0 - элемент списка 1, держать
1 - Список элемент 2, держать
2 - Список элемент 3, удалить , Все элементы сдвинуты, список теперь {1,2,4,5}.
3 - Список элемент 5, удалить
4 - элемент списка не упс, там больше нет 4

Так что я проскочил конец List, потому что я взял размер, чтобы быть 5, когда я начал итерацию, но это стало 4 после того, как я удалил элемент по индексу 2, и он стал 3, когда я удалил элемент по индексу 3.

Вы можете сказать: "Ах-ха, я могу это исправить с while цикла":

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

Но это еще хуже:

0 - элемент списка 1, держать
1 - Элемент списка 2, keep
2 - Элемент списка 3, удалить. Все элементы сдвинуты, список теперь {1,2,4,5}.
3 - Элемент списка 5, remove

Таким образом, никаких ошибок. Похоже, проблема исправлена. Но что содержит список? Он содержит {1,2,4}. Но 4 больше 3. Он был пропущен из-за сдвига индекса. У вас теперь еще более коварная ошибка.

Если вы используете правильный усиленную цикл Еогеасп как так:

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

вы бы, правильно, получил ConcurrentModificationException.Это всего лишь одна из многих причин использовать расширенный цикл foreach, а не цикл по индексу.

Для того, чтобы сделать то, что вы хотите использовать Iterator:

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

Я повторю свой комментарий:

Пожалуйста всегда использование Java naming conventions. Переменные всегда должны быть в camelCase. PascalCase зарезервирован для занятий.

UPDATE

Это может быть проще, так что используйте метод indexOf, чтобы найти имя команды в List и удалить необходимые элементы

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.

Вы можете использовать подвох

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

Т.е. продолжайте удалять элемент по найденному индексу, так как список будет перемешаться вниз, чтобы заполнить пробел, вы фактически удалите необходимый элемент и два, которые были над ним. Я думаю, что это делает код очень трудным для чтения. Вероятно, вы забудете этот трюк, а затем вернетесь к коду и должны решить, что он делает.

+0

Я не использовал Итераторы раньше, когда я пытаюсь. Я получаю ошибку «не могу найти символ Iterator класса». Кроме того, означает ли это, что список будет изменен, или теперь Итератор держит команды? – user3287269

+0

@ user3287269. Вы должны узнать об [import] (http://docs.oracle.com/javase/tutorial/java/package/usepkgs.html). «Итератор» не хранит данные; это реализация [Iterator Pattern] (http://en.wikipedia.org/wiki/Iterator_pattern) и проходит базовый «Список» (или «Итерируемый»). –

2

Теперь я использую два списка. Один из них - оригинал, другой - список удаления. Я прочитал первоначальный список, если запись начинается с «Team» (добавьте, если у вас есть другая логика для дифференциации имен команд от имен участников), я добавляю ее в список удаления, а также следующие записи до следующего имени команды для сохранения. Наконец, я удаляю все записи удаления из исходного списка.

public class ListRemovalDemo 
{ 
    public static void main(String[] args) 
    { 
      List<String> teamList = new ArrayList<String>(); 
      teamList.add("TeamName1"); 
      teamList.add("Member1Team1"); 
      teamList.add("Member2Team1"); 
      teamList.add("TeamName2"); 
      teamList.add("Member1Team2"); 
      teamList.add("Member2Team2"); 
      teamList.add("TeamName3"); 
      teamList.add("Member1Team3"); 
      teamList.add("Member2Team3"); 
      List<String> removalList = new ArrayList<String>(); 
      String teamToRemove = "TeamName2"; 
      Iterator<String> teamListIterator = teamList.listIterator(); 
      String entry; 
      while(teamListIterator.hasNext()) 
      { 
       entry = teamListIterator.next(); 
       if(entry.equals(teamToRemove)) 
       { 
        removalList.add(entry); 
        if(teamListIterator.hasNext()) 
        { 
         entry = teamListIterator.next(); 
          while(!entry.startsWith("Team")) 
          { 
           removalList.add(entry); 
           if(teamListIterator.hasNext()) 
            entry = teamListIterator.next(); 
           else 
            break; 
          } 
        } 
       } 
      } 
      teamList.removeAll(removalList); 
      System.out.println("After removal of " + teamToRemove + ":\n" + teamList); 
    } 
} 

выход

After removal of TeamName2: 
[TeamName1, Member1Team1, Member2Team1, TeamName3, Member1Team3, Member2Team3] 
+0

В случае выше, возможно, я не знаю членов команды. Но я узнаю название команды и хочу удалить как команду, так и ее участников. Мне нужно прокрутить список, чтобы найти команду, а затем удалить ее и следующие две строки. – user3287269

+0

. Я отредактировал свой ответ, чтобы показать новый код, который, я надеюсь, поможет вам –

Смежные вопросы