String.replaceAll and StringUtils.replace (assuming Apache Commons here) are two completely different beasts. The former is using a Regular Expression as search term and performs a replacement with support of Regular Expressions as well, the latter is just looking for occurrences of the given text and replaces it by the replacement text.

With String.replaceAll you can e.g. do something like this:

System.out.println("John Smith".replaceAll("^(\S+)\s*(\S+)\*2, $1"));

which will output

Smith, John

You can't do that with StringUtils.replace.

Assuming both libraries are available and we are not passing in a regex.

String.replaceAll is always parsing the search-term as Regex and performs the replacement assuming it to be using regex-functions as well, so it simply doesn't make sense to use this method without actually using Regex.

If you just want to do a simple text-replacement you just use String.replace(CharSequence c1, CharSequence c2) that was added with Java 1.5

From the few previous posts on this topic I see there are multiple tests and benchmarks pointing to that String.replace

Some sources would be nice, where you've seen that statement. The link Nexevis provided covered Java 1.4 where above method didn't exist and - without doing some tests myself now - I have doubts that the performance between String.replace(CharSequence...) and StringUtils.replace differ a lot because StringUtils' implementation looks quite straight forward and will most likely not differ a lot from the implementation in the JVM. The existence of it is purely historical because of the lack of a similar method in Java Version before 1.5

Answer from Lothar on Stack Overflow
Top answer
1 of 1
6

String.replaceAll and StringUtils.replace (assuming Apache Commons here) are two completely different beasts. The former is using a Regular Expression as search term and performs a replacement with support of Regular Expressions as well, the latter is just looking for occurrences of the given text and replaces it by the replacement text.

With String.replaceAll you can e.g. do something like this:

System.out.println("John Smith".replaceAll("^(\S+)\s*(\S+)\*2, $1"));

which will output

Smith, John

You can't do that with StringUtils.replace.

Assuming both libraries are available and we are not passing in a regex.

String.replaceAll is always parsing the search-term as Regex and performs the replacement assuming it to be using regex-functions as well, so it simply doesn't make sense to use this method without actually using Regex.

If you just want to do a simple text-replacement you just use String.replace(CharSequence c1, CharSequence c2) that was added with Java 1.5

From the few previous posts on this topic I see there are multiple tests and benchmarks pointing to that String.replace

Some sources would be nice, where you've seen that statement. The link Nexevis provided covered Java 1.4 where above method didn't exist and - without doing some tests myself now - I have doubts that the performance between String.replace(CharSequence...) and StringUtils.replace differ a lot because StringUtils' implementation looks quite straight forward and will most likely not differ a lot from the implementation in the JVM. The existence of it is purely historical because of the lack of a similar method in Java Version before 1.5

🌐
Apache Commons
commons.apache.org › proper › commons-lang › apidocs › deprecated-list.html
Deprecated List (Apache Commons Lang 3.20.0 API)
org.apache.commons.lang3.StringUtils.replaceAll · (String, String, String) Use RegExUtils.replaceAll(String, String, String). org.apache.commons.lang3.StringUtils.replaceFirst · (String, String, String) Use RegExUtils.replaceFirst(String, String, String). org.apache.commons.lang3.StringUtils.replaceIgnoreCase ·
🌐
GitHub
github.com › spring-cloud › spring-cloud-zookeeper › issues › 274
Replace usage of deprecated StringUtils.isEmpty with !StringUtils.hasLength · Issue #274 · spring-cloud/spring-cloud-zookeeper
December 4, 2020 - As of Spring 5.3 StringUtils.isEmpty is deprecated. The official migration hint is to either use one of the following: !StringUtils.hasLength !StringUtils.hasText To keep behaviour exactly the way it is, !StringUtils.hasLength can be use...
Published   Dec 04, 2020
🌐
GitHub
github.com › eclipse-che4z › che-che4z-lsp-for-cobol › issues › 112
Replace Usage of Deprecated Method StringUtils.getLevenshteinDistance · Issue #112 · eclipse-che4z/che-che4z-lsp-for-cobol
November 16, 2019 - Description There is a usage of a deprecated method StringUtils#getLevenshteinDistance() in CobolVisitor. It is recommended to replace it with LevensteinDistance of Apache commons-text. Technical details TPSR verification is required.
Published   Dec 16, 2019
🌐
GitHub
github.com › spring-projects › spring-data-mongodb › issues › 3613
Use StringUtils.replace(…) instead of String.replaceAll(…) for mapKeyDotReplacement · Issue #3613 · spring-projects/spring-data-mongodb
March 29, 2021 - * * @param source * @return */ protected String potentiallyUnescapeMapKey(String source) { return mapKeyDotReplacement == null ? source : source.replaceAll(mapKeyDotReplacement, "\\."); } Suggestion: Use org.springframework.util.StringUtils#replace or org.apache.commons.lang3.StringUtils#replace(java.lang.String, java.lang.String, java.lang.String) to replace dots instead.
Published   Mar 29, 2021
🌐
Tabnine
tabnine.com › home page › code › java › org.apache.commons.lang3.stringutils
org.apache.commons.lang3.StringUtils.replaceAll java code examples | Tabnine
Pattern.compile(regex).matcher(text).replaceAll(replacement) A null reference passed to this method is a no-op. Unlike in the #replacePattern(String,String,String) method, the Pattern#DOTALL option is NOT automatically added. To use the DOTALL option prepend "(?s)" to the regex. DOTALL is also known as single-line mode in Perl. StringUtils.replaceAll(null, *, *) = null StringUtils.replaceAll("any", (String) null, *) = "any" StringUtils.replaceAll("any", *, null) = "any" StringUtils.replaceAll("", "", "zzz") = "zzz" StringUtils.replaceAll("", ".*", "zzz") = "zzz" StringUtils.replaceAll("", ".+"
🌐
Apache Commons
commons.apache.org › proper › commons-lang › apidocs › index.html
Overview (Apache Commons Lang 3.18.0 API)
Deprecated: Provides classes for handling and manipulating text, partly as an extension to java.text.
🌐
Apache Commons
commons.apache.org › proper › commons-lang › javadocs › api-release › org › apache › commons › lang3 › StringUtils.html
StringUtils (Apache Commons Lang 3.11 API)
StringUtils.chomp(null) = null StringUtils.chomp("") = "" StringUtils.chomp("abc \r") = "abc " StringUtils.chomp("abc\n") = "abc" StringUtils.chomp("abc\r\n") = "abc" StringUtils.chomp("abc\r\n\r\n") = "abc\r\n" StringUtils.chomp("abc\n\r") = "abc\n" StringUtils.chomp("abc\n\rabc") = "abc\n\rabc" StringUtils.chomp("\r") = "" StringUtils.chomp("\n") = "" StringUtils.chomp("\r\n") = "" ... Deprecated.
Find elsewhere
🌐
Apache Commons
commons.apache.org › proper › commons-lang › javadocs › api-3.9 › org › apache › commons › lang3 › RegExUtils.html
RegExUtils (Apache Commons Lang 3.9 API)
StringUtils.removeFirst(null, *) ... StringUtils.removeFirst("ABCabc123abc", "[a-z]+") = "ABC123abc" ... Removes each substring of the source String that matches the given regular expression using the DOTALL option. This call is a null safe equivalent to: text.replaceAll("(?s)" ...
🌐
Igniterealtime
download.igniterealtime.org › openfire › docs › 4.5.6 › documentation › javadoc › org › jivesoftware › util › StringUtils.html
StringUtils (Core XMPP Server 4.5.4 API)
public final class StringUtils ... String oldString, String newString) Deprecated. Use String.replaceAll(String, String)} Replaces all instances of oldString with newString in string....
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › lang › String.html
String (Java Platform SE 8 )
October 20, 2025 - An invocation of this method of the form str.replaceAll(regex, repl) yields exactly the same result as the expression
Top answer
1 of 5
66

In modern Java, this is not the case anymore. String.replace was improved in Java-9 moving from regular expression to StringBuilder, and was improved even more in Java-13 moving to direct allocation of the target byte[] array calculating its exact size in advance. Thanks to internal JDK features used, like the ability to allocate an uninitialized array, ability to access String coder and ability to use private String constructor which avoids copying, it's unlikely that current implementation can be beaten by a third-party implementation.

Here are my benchmarking results for your test using JDK 8, JDK 9 and JDK 13 (caliper:0.5-rc1; commons-lang3:3.9)

Java 8 (4x slower indeed):

 0% Scenario{vm=java, trial=0, benchmark=M1} 291.42 ns; σ=6.56 ns @ 10 trials
50% Scenario{vm=java, trial=0, benchmark=M2} 70.34 ns; σ=0.15 ns @ 3 trials

benchmark    ns linear runtime
       M1 291.4 ==============================
       M2  70.3 =======

Java 9 (almost equal performance):

 0% Scenario{vm=java, trial=0, benchmark=M2} 99,15 ns; σ=8,34 ns @ 10 trials
50% Scenario{vm=java, trial=0, benchmark=M1} 103,43 ns; σ=9,01 ns @ 10 trials

benchmark    ns linear runtime
       M2  99,1 ============================
       M1 103,4 ==============================

Java 13 (standard method is 38% faster):

 0% Scenario{vm=java, trial=0, benchmark=M2} 91,64 ns; σ=5,12 ns @ 10 trials
50% Scenario{vm=java, trial=0, benchmark=M1} 57,38 ns; σ=2,51 ns @ 10 trials

benchmark   ns linear runtime
       M2 91,6 ==============================
       M1 57,4 ==================
2 of 5
44

From the source code of java.lang.String1:

public String replace(CharSequence target, CharSequence replacement) {
   return Pattern
            .compile(target.toString(), Pattern.LITERAL)
            .matcher(this )
            .replaceAll(
                    Matcher.quoteReplacement(replacement.toString()));
}

String.replace(CharSequence target, CharSequence replacement) is implemented with java.util.regex.Pattern, therefore, it is not surprising that it is slower that StringUtils.replace(String text, String searchString, String replacement)2, which is implemented with indexOf and StringBuffer.

public static String replace(String text, String searchString, String replacement) {
    return replace(text, searchString, replacement, -1);
}

public static String replace(String text, String searchString, String replacement, int max) {
    if (isEmpty(text) || isEmpty(searchString) || replacement == null || max == 0) {
        return text;
    }
    int start = 0;
    int end = text.indexOf(searchString, start);
    if (end == -1) {
        return text;
    }
    int replLength = searchString.length();
    int increase = replacement.length() - replLength;
    increase = (increase < 0 ? 0 : increase);
    increase *= (max < 0 ? 16 : (max > 64 ? 64 : max));
    StringBuffer buf = new StringBuffer(text.length() + increase);
    while (end != -1) {
        buf.append(text.substring(start, end)).append(replacement);
        start = end + replLength;
        if (--max == 0) {
            break;
        }
        end = text.indexOf(searchString, start);
    }
    buf.append(text.substring(start));
    return buf.toString();
}

Footnote

1 The version that I links to and copied source code from is JDK 7

2 The version that I links to and copied source code from is common-lang-2.5

🌐
Medium
medium.com › javarevisited › micro-optimizations-in-java-string-replaceall-c6d0edf2ef6
Micro optimizations in Java. String.replaceAll | by Dmytro Dumanskiy | Javarevisited | Medium
September 8, 2020 - Before Java 11, when you had a hot path with the String.replace method, you had to find the faster alternatives in some 3-d party libraries or even write your own custom version. The most known 3-d party alternative is the Apache Commons StringUtils.replace method.
🌐
GitHub
github.com › DSpace › DSpace › issues › 11162
org.apache.commons.lang3.StringUtils has some deprecated methods · Issue #11162 · DSpace/DSpace
August 15, 2025 - Describe the bug There are a handful of warnings about deprecated methods from org.apache.commons.lang3.StringUtils during the build. Here are some examples: [WARNING] dspace-api/src/main/java/org/dspace/eperson/Group.java:[202,24] [depr...
Published   Aug 15, 2025
🌐
Scijava
javadoc.scijava.org › Apache-Commons-Lang › org › apache › commons › lang3 › RegExUtils.html
RegExUtils (Apache Commons Lang 3.12.0 API)
StringUtils.removeFirst(null, *) ... StringUtils.removeFirst("ABCabc123abc", "[a-z]+") = "ABC123abc" ... Removes each substring of the source String that matches the given regular expression using the DOTALL option. This call is a null safe equivalent to: text.replaceAll(&quot;(?s)&quot; ...
🌐
JavaBeat
javabeat.net › home › how to use string.replaceall() method in java
How to Use String.replaceAll() Method in Java
March 12, 2024 - This Java post has extensively explained the working of the replaceAll() method, its different use cases, alternatives, and possible exceptions. Anees, a go-to expert of various technologies like PostgreSQL, Java, JS, and Linux. He has been contributing to the community through his words. A passion for serving the people excites him to craft primo content. Previous Post: « How to Use String substring() Method in Java · Next Post: How to Use StringUtils Class in Java »