Marko's answer is clearly among the best for the programming endeavor in this question.
However, using this as a general example from which one can extrapolate to contexts where there is no such better solution (as regexp or CharMatcher), as a matter of style and practice, I use and recommend simpler expressions, capturing what would otherwise be repeated method call results using local variables.
I assert that this improves clarity as we can name the local variables, and allows us to locate each simpler piece of code in the most logical place for execution (while also allowing the JVM to optimize one thing it is really good at, namely local variable usage).
You'll notice here in this transformed version, that we test firstChar outside the loop, instead of repeatedly inside the loop; same with .length() . I would first argue that this is logically more correct programming (it is confusing to other readers as to why this might be done over and over in the loop), and only second that it will have better performance.
While such code motion of the loop will not materially effect performance of this simple example (with a mere count of 5 iterations, and where there are better solutions using libraries that loop for us), in general and in other contexts, I recommend this as best practice, more readable, and cleaner (while also being performance oriented).
Also note, I test length first, so that .charAt(0) is known to exist, ie the length is > 0, meaning that we will reportError()
on zero length string, instead of throwing some IndexOutOfBounds
. This is another example of how using simpler expressions allows superior ordering of the programming logic.
This KIS (keep-it-simple) style also makes debugging easier as these local variables can trivially be watched. I think it is more readable for maintainers as well.
Also, confining the constant 5 to one place eases maintenance.
public static final int expectedLength = 5;
...
if ( codeInput.length() != expectedLength )
return reportError ();
char firstChar = codeInput.charAt(0);
if ( firstChar < 'A' || firstChar > 'Z' )
return reportError ();
for (int i = 1; i < expectedLength; i++) {
char nextChar = codeInput.charAt(i);
if ( nextChar < '0' || nextChar > '9' )
return reportError ();
}
...
private static boolean reportError () {
if (verbose)
System.out.println("Sorry, I don't understand!\nUse product codes only.");
return true;
}