The problem is with st.nextToken()
call.
You are checking st.hasMoreTokens()
only once but calling st.nextToken()
twice. And it is throwing the error.
During 1st while
loop you are reading all the tokens:
while(st.hasMoreTokens()) {
tokens.add(st.nextToken());
}
Since 'all' the tokens are already read, now when you try to read the token again inside the for
loop you will get the error.
if(st.nextToken() == key) {
trace.add(key + "Changed from " + expression.get(key) + " to " + tokens.get(2));
}
There is also another potential problem. You are trying to convert the 3rd token to an Integer. It might fail there as well:
// Value of tokens.get(2) is "string"
Integer.parseInt(tokens.get(2))
You will get error here also. It would be good to check if tokens.get(2)
is of numeric type or not. like:
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);
Reference: StringUtils.isNumeric()
So, the modified code will be like:
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();
}