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