-1

Я пытаюсь увидеть, соответствует ли следующий токен в строке эквивалентным ключу карты и добавляет сообщение в список массивов.Ошибка NoSuchElementException

ArrayList<String> trace = new ArrayList<String>(); 
if(!element.startsWith("PRINT")) { 
      while(st.hasMoreTokens()) { 
       tokens.add(st.nextToken()); 
      } 

      for(String key: expression.keySet()) 
       if(st.nextToken() == key) 
        trace.add(key + "Changed from " + expression.get(key) + " to " + tokens.get(2)); 

      expression.put(tokens.get(0),Integer.parseInt(tokens.get(2))); 
      tokens.clear(); 
} 

ERROR MESSAGE

Exception in thread "main" java.util.NoSuchElementException 
    at java.util.StringTokenizer.nextToken(StringTokenizer.java:349) 
    at Commander.main(Commander.java:45) 
+3

Что такое 'element'? – Rustam

+1

Заменить if (st.nextToken() == key) с if (st.hasMoreTokens() && st.nextToken() == key), я думаю, что это решит вашу проблему. – RE350

+1

Вне того, что вы не можете сравнивать строки с '==' (это то, что делает 'st.nextToken() == key', не делайте этого), вы не укажете, что ваш токенизатор пробирая вещи, и вы не указываете, какова ваша начальная строка ввода. – Makoto

ответ

3

Проблема с st.nextToken() вызова.

Вы проверяете st.hasMoreTokens() один раз, но вызываете st.nextToken() дважды. И это бросает ошибку.

В течение 1-го while цикла вы читаете все маркеры:

while(st.hasMoreTokens()) { 
    tokens.add(st.nextToken()); 
} 

Так как «все» лексемы уже читали, теперь, когда вы пытаетесь прочитать маркер снова внутри цикла for вы получите сообщение об ошибке ,

if(st.nextToken() == key) { 
    trace.add(key + "Changed from " + expression.get(key) + " to " + tokens.get(2)); 
} 

Существует еще одна потенциальная проблема. Вы пытаетесь преобразовать 3-й токен в Integer. Он также может потерпеть неудачу:

// Value of tokens.get(2) is "string" 
Integer.parseInt(tokens.get(2)) 

Здесь вы также получите сообщение об ошибке. Было бы неплохо проверить, является ли tokens.get(2) числовым или нет. как:

int value = 0; 
if (StringUtils.isNumeric(tokens.get(2))) { 
    value = Integer.parseInt(tokens.get(2)); 
} 
// Default value will be 0. 
expression.put(tokens.get(0), value); 

Ссылка: StringUtils.isNumeric()

Таким образом, измененный код будет как:

ArrayList<String> trace = new ArrayList<String>(); 
if(!element.startsWith("PRINT")) { 
    List<String> tokens = new ArrayList<String>(); 
    while(st.hasMoreTokens()) { 
     tokens.add(st.nextToken()); 
    } 

    // Size of tokens has to be more then 3, otherwise you will get another error. 
    if (tokens.size() >= 3) { 
     for(String key: expression.keySet()) { 
      if(tokens.get(0).equals(key)) { 
       // Do your other operations... 
       trace.add(key + "Changed from " + expression.get(key) + " to " + tokens.get(2)); 
      } 
     } 

     // Do some more operations ... 
     int value = 0; 
     if (StringUtils.isNumeric(tokens.get(2))) { 
      value = Integer.parseInt(tokens.get(2)); 
     } 
     // Default value will be 0. 
     expression.put(tokens.get(0), value); 
    } 
    tokens.clear(); 
} 
Смежные вопросы