8303648: Add String.indexOf(String str, int beginIndex, int endIndex)

Reviewed-by: rriggs
This commit is contained in:
Raffaello Giulietti 2023-03-21 08:43:23 +00:00
parent c4df9b5f17
commit 4bf1fbb06d
2 changed files with 247 additions and 15 deletions

View file

@ -2607,6 +2607,19 @@ public final class String
* }</pre>
* If no such value of {@code k} exists, then {@code -1} is returned.
*
* @apiNote
* Unlike {@link #substring(int)}, for example, this method does not throw
* an exception when {@code fromIndex} is outside the valid range.
* Rather, it returns -1 when {@code fromIndex} is larger than the length of
* the string.
* This result is, by itself, indistinguishable from a genuine absence of
* {@code str} in the string.
* If stricter behavior is needed, {@link #indexOf(String, int, int)}
* should be considered instead.
* On {@link String} {@code s} and a non-empty {@code str}, for example,
* {@code s.indexOf(str, fromIndex, s.length())} would throw if
* {@code fromIndex} were larger than the string length, or were negative.
*
* @param str the substring to search for.
* @param fromIndex the index from which to start the search.
* @return the index of the first occurrence of the specified substring,
@ -2617,6 +2630,39 @@ public final class String
return indexOf(value, coder(), length(), str, fromIndex);
}
/**
* Returns the index of the first occurrence of the specified substring
* within the specified index range of {@code this} string.
*
* <p>This method returns the same result as the one of the invocation
* <pre>{@code
* s.substring(beginIndex, endIndex).indexOf(str) + beginIndex
* }</pre>
* if the index returned by {@link #indexOf(String)} is non-negative,
* and returns -1 otherwise.
* (No substring is instantiated, though.)
*
* @param str the substring to search for.
* @param beginIndex the index to start the search from (included).
* @param endIndex the index to stop the search at (excluded).
* @return the index of the first occurrence of the specified substring
* within the specified index range,
* or {@code -1} if there is no such occurrence.
* @throws StringIndexOutOfBoundsException if {@code beginIndex}
* is negative, or {@code endIndex} is larger than the length of
* this {@code String} object, or {@code beginIndex} is larger than
* {@code endIndex}.
* @since 21
*/
public int indexOf(String str, int beginIndex, int endIndex) {
if (str.length() == 1) {
/* Simple optimization, can be omitted without behavioral impact */
return indexOf(str.charAt(0), beginIndex, endIndex);
}
checkBoundsBeginEnd(beginIndex, endIndex, length());
return indexOf(value, coder(), endIndex, str, beginIndex);
}
/**
* Code shared by String and AbstractStringBuilder to do searches. The
* source is the character array being searched, and the target
@ -2624,28 +2670,23 @@ public final class String
*
* @param src the characters being searched.
* @param srcCoder the coder of the source string.
* @param srcCount length of the source string.
* @param srcCount last index (exclusive) in the source string.
* @param tgtStr the characters being searched for.
* @param fromIndex the index to begin searching from.
*/
static int indexOf(byte[] src, byte srcCoder, int srcCount,
String tgtStr, int fromIndex) {
byte[] tgt = tgtStr.value;
byte tgtCoder = tgtStr.coder();
int tgtCount = tgtStr.length();
if (fromIndex >= srcCount) {
return (tgtCount == 0 ? srcCount : -1);
}
if (fromIndex < 0) {
fromIndex = 0;
fromIndex = Math.clamp(fromIndex, 0, srcCount);
int tgtCount = tgtStr.length();
if (tgtCount > srcCount - fromIndex) {
return -1;
}
if (tgtCount == 0) {
return fromIndex;
}
if (tgtCount > srcCount) {
return -1;
}
byte[] tgt = tgtStr.value;
byte tgtCoder = tgtStr.coder();
if (srcCoder == tgtCoder) {
return srcCoder == LATIN1
? StringLatin1.indexOf(src, srcCount, tgt, tgtCount, fromIndex)