lastIndexOf(int ch)
will start from the end and search backwards, returning the absolute index of the last occurrence. Then you could subtract that number from the length of the String and negate it, if that's what you really want.
You can also use lastIndexOf(int ch, int fromIndex)
if you want to search backwards from a particular index.
To answer your question about what happens when you pass a negative number, you can dig into the source code for the String class. As it turns out, the indexOf
implementation that is ultimately called resets a negative fromIndex
value to zero:
static int indexOf(char[] source, int sourceOffset, int sourceCount,
char[] target, int targetOffset, int targetCount,
int fromIndex) {
if (fromIndex >= sourceCount) {
return (targetCount == 0 ? sourceCount : -1);
}
if (fromIndex < 0) {
fromIndex = 0;
}
...
Getting back to your second example:
"abcd".indexOf("d",-0)
...implementing a generic indexOf which accepts a negative index and returns the appropriate negative index (if there is one) is more complicated because Java does not distinguish between int
0
and int
-0
(both will be represented as 0), and because String.indexOf normally returns -1 if the search string is not found. However, you can get close to what you want. Note there are a few caveats:
String.indexOf
normally returns -1
if the search string is not found. But because -1
is a valid index in our new implementation, we need to define a new contract. Integer.MIN_VALUE
is now returned if the search string is not found.
- Because we cannot test for
int
-0
, we cannot refer to the index of the last character as -0
. For that reason, we use -1
to refer to the index of the last character, and continue counting backwards from there.
- For consistency with item 2, negative return values also start counting down starting with
-1
as the index of the last character.
The code could be simplified, but I've intentionally made it verbose so you can easily step through it in a debugger.
package com.example.string;
public class StringExample {
public static int indexOf(String str, String search, int fromIndex) {
if (fromIndex < 0) {
fromIndex = str.length() + fromIndex; // convert the negative index to a positive index, treating the negative index -1 as the index of the last character
int index = str.lastIndexOf(search, fromIndex);
if (index == -1) {
index = Integer.MIN_VALUE; // String.indexOf normally returns -1 if the character is not found, but we need to define a new contract since -1 is a valid index for our new implementation
}
else {
index = -(str.length() - index); // convert the result to a negative index--again, -1 is the index of the last character
}
return index;
}
else {
return str.indexOf(str, fromIndex);
}
}
public static void main(String[] args) {
System.out.println(indexOf("abcd", "d", -1)); // returns -1
System.out.println(indexOf("adbcd", "d", -2)); // returns -4
}
}
"dabcd".indexOf("d",-0)
? (FYI, you don't need to declare a new String each time; you can call String methods directly on a String literal) – Mahala