< prev index next >

src/java.base/share/classes/java/lang/String.java

Print this page

        

@@ -35,11 +35,10 @@
 import java.util.Locale;
 import java.util.Objects;
 import java.util.Spliterator;
 import java.util.StringJoiner;
 import java.util.function.IntConsumer;
-import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
 import java.util.stream.IntStream;
 import java.util.stream.StreamSupport;
 

@@ -2245,12 +2244,91 @@
      * @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()));
+        final String starget = target.toString();
+        final int targLen = starget.length();
+        final String srepl = replacement.toString();
+
+        // 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;
+        }
+
+        class Substring {
+            final int begin, end;
+            Substring next;
+            Substring(int begin, int end) {
+                this.begin = begin; this.end = end;
+            }
+            int length() {
+                return end - begin;
+            }
+            int getChars(char[] dst, int dstBegin) {
+                String.this.getChars(begin, end, dst, dstBegin);
+                return dstBegin + end - begin;
+            }
+        }
+
+        final int repLen = srepl.length();
+        final Substring first = new Substring(0, i);
+        Substring ss = first;
+        int resLen = ss.length();
+        i += targLen;
+        int j;
+        while ((j = indexOf(starget, i)) > 0) {
+            ss = ss.next = new Substring(i, j);
+            resLen += repLen + ss.length();
+            i = j + targLen;
+        }
+        ss = ss.next = new Substring(i, length());
+        resLen += repLen + ss.length();
+
+        char[] res = new char[resLen];
+        for (ss = first, i = 0; ss != null; ) {
+            i = ss.getChars(res, i);
+            ss = ss.next;
+            if (ss != null) {
+                srepl.getChars(res, i);
+                i += repLen;
+            }
+        }
+        return new String(res, 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) {
+        if (isEmpty()) {
+            return delimiter;
+        }
+        int delimLen = delimiter.length();
+        if (delimLen == 0) {
+            return this;
+        }
+        int resLen = length() + (length() + 1) * delimLen;
+        char[] res = new char[resLen];
+        int j = 0;
+        for (int i = 0; i < length(); i++) {
+            delimiter.getChars(res, j);
+            j += delimLen;
+            res[j++] = charAt(i);
+        }
+        delimiter.getChars(res, j);
+        return new String(res, true);
     }
 
     /**
      * Splits this string around matches of the given
      * <a href="../util/regex/Pattern.html#sum">regular expression</a>.
< prev index next >