Ответ 1
lastIndexOf(int ch)
начнется с конца и начнет поиск назад, возвращая абсолютный индекс последнего вхождения. Затем вы можете вычесть это число из длины строки и отрицать его, если это то, что вы действительно хотите.
Вы также можете использовать lastIndexOf(int ch, int fromIndex)
, если вы хотите искать назад от определенного индекса.
Чтобы ответить на вопрос о том, что происходит, когда вы передаете отрицательное число, вы можете вставить исходный код для класса String. Как оказалось, реализация indexOf
, которая в конечном итоге называется, сбрасывает отрицательное значение fromIndex
в ноль:
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;
}
...
Возвращаясь к вашему второму примеру:
"abcd".indexOf("d",-0)
... реализация универсального indexOf, который принимает отрицательный индекс и возвращает соответствующий отрицательный индекс (если он есть), более сложный, поскольку Java не различает int
0
и int
-0
( оба будут представлены как 0), и поскольку String.indexOf обычно возвращает -1, если строка поиска не найдена. Однако вы можете приблизиться к тому, что хотите. Обратите внимание, что есть несколько предостережений:
-
String.indexOf
обычно возвращает-1
, если строка поиска не найдена. Но поскольку-1
является допустимым индексом в нашей новой реализации, нам нужно определить новый контракт.Integer.MIN_VALUE
теперь возвращается, если строка поиска не найдена. - Поскольку мы не можем проверить
int
-0
, мы не можем ссылаться на индекс последнего символа как-0
. По этой причине мы используем-1
для обозначения индекса последнего символа и продолжаем считать назад оттуда. - Для согласования с пунктом 2 отрицательные возвращаемые значения также начинают отсчет, начиная с
-1
в качестве индекса последнего символа.
Код может быть упрощен, но я намеренно сделал его подробным, чтобы вы могли легко выполнить его в отладчике.
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
}
}