An IDE warning

exercise No. 211

Q:

We consider:

01 /**
02 * <p>Check a string for ending with a particular character.</p>
03 *
04 * <p>Example: <code>"Environment"</code> ends with character <code>'t'</code>.</p>
05 *
06 * @param s The string to be inspected.
07 * @param c The char to be searched for.
08 * @return true if s ends with character c, false otherwise
09 */
10
11 static boolean endsWith (final String s, final char c) {
12    return s.indexOf(c) == s.length();
13 }

The IDE issues a warning corresponding to line 12:

Condition 's.indexOf(c) == s.length()' is always 'false' 

Explain the underlying flaw and provide a fix.

  1. Why is the condition always true?

  2. Is there some other related problem?

  3. Fix the implementation to fulfill the Javadoc description.

Tip

You may want to consult the String.indexOf(int) method's description.

A:

The indexOf(int) method returns:

  • The index of the char's first occurrence in the given string.

  • -1 if the string does not contain that character.

  1. For a given string s the very last character has got the index value s.length() - 1. The maximum possible inclusive value of s.indexOf(c) is thus s.length() - 1 and can therefore never exceed s.length(). Correcting this error reads:

    static boolean endsWith (final String s, final char c) {
       return s.indexOf(c) == s.length() - 1;
    }
  2. Unfortunately a character may appear multiple times within a given String: E.g., "HaHa".indexOf('a') evaluates to the first index 1 rather than 3, thus indicating the first occurrence of 'a' within the string.

  3. A correct implementation reads:

    static boolean endsWith (final String s, final char c) {
       return s.lastIndexOf(c) == s.length() - 1;
    }

    Alternate solution avoiding fiddling with index values:

    static boolean endsWith (final String s, final char c) {
       s.endsWith(Character.toString(c));
    }