< prev index next >
src/java.base/share/classes/java/lang/String.java
Print this page
rev 12026 : [mq]: 8058779-Faster-implementation-of-String-replace-HEAVYDUTY
*** 2233,2242 ****
--- 2233,2250 ----
public String replaceAll(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}
/**
+ * The maximum size of array to allocate.
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
+ */
+ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
+ /**
* Replaces each substring of this string that matches the literal target
* sequence with the specified literal replacement sequence. The
* replacement proceeds from the beginning of the string to the end, for
* example, replacing "aa" with "b" in the string "aaa" will result in
* "ba" rather than "ab".
*** 2245,2256 ****
* @param replacement The replacement sequence of char values
* @return The resulting string
* @since 1.5
*/
public String replace(CharSequence target, CharSequence replacement) {
! return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(
! this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
}
/**
* Splits this string around matches of the given
* <a href="../util/regex/Pattern.html#sum">regular expression</a>.
--- 2253,2370 ----
* @param replacement The replacement sequence of char values
* @return The resulting string
* @since 1.5
*/
public String replace(CharSequence target, CharSequence replacement) {
! String starget = target.toString();
! int targLen = starget.length();
! String srepl = replacement.toString();
! int replLen = srepl.length();
!
! // special case: replacing empty substrings
! if (targLen == 0) {
! return splitAndJoin(srepl);
! }
!
! int i = indexOf(starget);
! // special case: nothing to replace
! if (i < 0) {
! return this;
! }
!
! // find and store indices of substrings to replace
! int p = 0, j;
! int[] pos = new int[16];
! pos[0] = i;
! i += targLen;
! while ((j = indexOf(starget, i)) > 0) {
! if (++p == pos.length) {
! int cap = p << 1;
! // overflow-conscious code
! if (p >= MAX_ARRAY_SIZE - p) {
! if (p == MAX_ARRAY_SIZE)
! throw new OutOfMemoryError();
! cap = MAX_ARRAY_SIZE;
! }
! pos = Arrays.copyOf(pos, cap);
! }
! pos[p] = j;
! i = j + targLen;
! }
!
! final char[] value = this.value;
! final char[] replValue = srepl.value;
! int thisLen = value.length;
! int deltaLen = replLen - targLen;
! // overflow-conscious code
! int resultLen = thisLen + (p + 1) * deltaLen;
! if (MAX_ARRAY_SIZE / (p + 1) < deltaLen ||
! MAX_ARRAY_SIZE - resultLen < 0) {
! throw new OutOfMemoryError();
! }
! if (resultLen <= 0) {
! return "";
! }
!
! char[] result = new char[resultLen];
! int posFrom = 0, posTo = 0;
! for (int q = 0; q <= p; ++q) {
! int nextPos = pos[q];
! int lenInc = nextPos - posFrom;
! if (lenInc > 0) {
! System.arraycopy(value, posFrom, result, posTo, lenInc);
! posTo += lenInc;
! }
! if (replLen > 0) {
! System.arraycopy(replValue, 0, result, posTo, replLen);
! posTo += replLen;
! }
! posFrom = nextPos + targLen;
! }
! System.arraycopy(value, posFrom, result, posTo,
! thisLen - posFrom);
!
! return new String(result, true);
! }
!
! /**
! * Returns this string with every empty substring
! * replaced by the given delimiter.
! * If this string is empty, the delimiter is returned.
! * If the delimiter is empty, unchanged this string
! * is returned.
! */
! private String splitAndJoin(String delimiter) {
! final char[] value = this.value;
! int thisLen = value.length;
! if (thisLen == 0) {
! return delimiter;
! }
!
! final char[] delimValue = delimiter.value;
! int delimLen = delimValue.length;
! if (delimLen == 0) {
! return this;
! }
!
! // overflow-conscious code
! int resultLen = thisLen + (thisLen + 1) * delimLen;
! if (MAX_ARRAY_SIZE / (thisLen + 1) < delimLen ||
! MAX_ARRAY_SIZE - resultLen < 0) {
! throw new OutOfMemoryError();
! }
!
! char[] result = new char[resultLen];
! int posFrom = 0, posTo = 0;
! while (posFrom < thisLen) {
! System.arraycopy(delimValue, 0, result, posTo, delimLen);
! posTo += delimLen;
! result[posTo++] = value[posFrom++];
! }
! System.arraycopy(delimValue, 0, result, posTo, delimLen);
!
! return new String(result, true);
}
/**
* Splits this string around matches of the given
* <a href="../util/regex/Pattern.html#sum">regular expression</a>.
< prev index next >