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.

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.

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;
}

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. The correct solution therefore 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));
}