Check if a String is a valid Double
There are three validation failures (ignoring case sensitivity) that Double.parseDouble() would have accepted otherwise:


A starting positive sign (+1.23).
A starting decimal point (.123).
The E notation aka scientific notation (1.23E4).


As for your comments... they should explain the why, not the how. The comments you have now are only explaining the how, so you should consider removing them when you get the chance to write code outside of academic exercises in the future...

Variable names... it depends. i is quite well-understood, but some may frown upon a single c to represent a character, or even str for your method argument... I'm not suggesting to be overly descriptive (currentCharacterOfMethodArgument is an example), but maybe an actual English word (current?) might be slightly more readable for your marker.

And just for completeness, remember to do a null check at the start too, before str.isEmpty(). :)

edit And since you asked about it, the implementation of charAt(int) is just:

public char charAt(int index) {
    if ((index &lt; 0) || (index &gt;= value.length)) {
        throw new StringIndexOutOfBoundsException(index);
    }
    return value[index];
}


The only 'evaluation' here is the if statement for out-of-bounds check, which I don't think is that significant/performance-hurting (if you're alluding to this indirectly as well). It's fine both ways whether you want to 'cache' it first.