Search code examples
javaindexoutofboundsexceptionstringindexoutofbounds

getting StringIndexOutOfBound Exception


I am writing a program to accept user name and password using following conditions- username must be min 8 characters. Password must have min 10 characters, 1 lowerCase, 1 upperCase, 1 digit should present in the password. I wrote a method setPassword() following all the conditions. When I try to execute I am getting StringIndexOutOfBound exception. I am unable to understand why I am getting that error:

public void setPassword(String password)
{
    char ch;
    if (password.length() <= 10) {
        for (int i = 0; i <= password.length() - 1; i++) {
            ch = password.charAt(i);
            if (Character.isDigit(ch)) {
                for (int j = 0; j <= password.length() - 1; j++) {
                    char ch1 = password.charAt(j);
                    if (Character.isUpperCase(ch1)) {
                        for(int k = 0; k <= password.length(); k++) {
                            char ch2 = password.charAt(k);
                            if (Character.isLowerCase(ch2)) {
                                this.password = password;
                            }
                        }
                    }
                }
            }
        }
    }
}

Solution

  • Ignoring the inefficiencies of this implementation, the following line:

    for(int k = 0; k <= password.length(); k++) {
    

    Should either be:

    for(int k = 0; k < password.length(); k++) {
    //                ^ removed the = from here
    

    Or:

    for(int k = 0; k <= password.length() - 1; k++) {
    //                                    ^ subtract 1 here
    

    For the following string:

    String s = "this-is-a-test";
    

    s.length() is going to return 14. The valid indices of characters in that string are 0 through 13. The idiomatic way of iterating over an array with a for loop is:

    for (int i = 0; i < length_of_array; i++)
    

    You've opted to instead use i <= length_of_array - 1 which is effectively the same thing (albeit more verbose), except for your last for loop where you neglect to subtract 1 from the length.

    Here is a simplistic method for checking password validity based on the criteria you provided:

    public static boolean isPasswordValid(String password)
    {
        if (password.length() < 10) {
            return false;
        }
    
        int lc = 0, uc = 0, digit = 0;
    
        for (int i = 0; i < password.length(); i++) {
            char c = password.charAt(i);
    
            if (Character.isLowerCase(c)) {
                lc++;
            } else if (Character.isUpperCase(c)) {
                uc++;
            } else if (Character.isDigit(c)) {
                digit++;
            }
        }
    
        return lc > 0 && uc > 0 && digit > 0;
    }
    

    This will return true if all of the conditions pass, and false otherwise.