Question 16 Β· Section 12

Difference Between replace() vs replaceAll()

Both methods replace all found occurrences. The difference is how they search:

Language versions: English Russian Ukrainian

🟒 Junior Level

Both methods replace all found occurrences. The difference is how they search:

replace() β€” searches for plain text (literal):

String s = "apple.banana.orange";
System.out.println(s.replace(".", "/"));
// "apple/banana/orange" β€” dot is searched literally

replaceAll() β€” searches by regular expression:

String s = "apple.banana.orange";
System.out.println(s.replaceAll(".", "/"));
// "/////////////////" β€” dot in regex = "any character"!

Main trap: The name replace is misleading β€” it replaces ALL occurrences, not the first one. For replacing only the first occurrence, there’s replaceFirst().


🟑 Middle Level

Method comparison

Method What searches Replaces Speed
replace(char, char) Character All Fastest
replace(CharSequence, CharSequence) Literal (text) All Fast
replaceAll(String regex, String replacement) Regular expression All Slow
replaceFirst(String regex, String replacement) Regular expression First Slow

Practical application

// replace β€” for plain text
s.replace("old", "new");        // Literal replacement
s.replace('a', 'b');            // Character replacement

// replaceAll β€” for patterns
s.replaceAll("\\d+", "#");      // All digits β†’ #
s.replaceAll("\\s+", " ");      // Multiple spaces β†’ one

// replaceFirst β€” only first match
s.replaceFirst("\\d", "#");     // Only first digit

Typical mistakes

  1. Mistake: replaceAll("user.name", "admin") β€” dot = any character Solution: replaceAll(Pattern.quote("user.name"), "admin") or replace("user.name", "admin")

  2. Mistake: Thinking replace changes only the first one Solution: replace changes ALL. For first β€” replaceFirst

  3. Mistake: $ in replacement string for replaceAll Solution: $1, $2 β€” group references. For literal $ use Matcher.quoteReplacement("$")


πŸ”΄ Senior Level

Internal Implementation

replace(CharSequence, CharSequence) β€” via Pattern.LITERAL replace(char, char) β€” separate method, direct byte[] scan, NO Pattern

public String replace(CharSequence target, CharSequence replacement) {
    // Check Fast Path for single char
    if (target instanceof String && replacement instanceof String) {
        String tgt = (String) target;
        String repl = (String) replacement;
        if (tgt.length() == 1 && repl.length() == 1) {
            return replace(tgt.charAt(0), repl.charAt(0));
        }
    }
    // Via Pattern/Literal replacement β€” no regex engine
    return Pattern.compile(target.toString(), Pattern.LITERAL)
                  .matcher(this)
                  .replaceAll(Matcher.quoteReplacement(replacement.toString()));
}

replaceAll(String regex, String replacement):

public String replaceAll(String regex, String replacement) {
    return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}

Key difference: replace uses Pattern.LITERAL (literal matching), replaceAll β€” full regex engine.

Architectural Trade-offs

replace (literal):

  • Pros: No regex overhead, safe with special characters, predictable
  • Cons: No patterns, groups, backreferences

replaceAll (regex):

  • Pros: Full regex power (groups, lookahead, backreferences)
  • Cons: Regex compilation, allocations, special characters need escaping

Performance Comparison

Method Mechanism Allocations 1M calls
replace('a', 'b') Direct byte[] pass 1 String ~10ms
replace("ab", "cd") indexOf + copy 1 String + Pattern ~50ms
replaceAll("a.b", "x") Regex compile + match Pattern + Matcher + String ~300ms
replaceAll(precompiled, "x") Match only Matcher + String ~80ms

// Numbers are approximate, depend on JVM and string length.

Edge Cases

  1. Regex metacharacters in replaceAll:
    s.replaceAll("path\\to\\file", "/new"); // \t = tab, \f = form feed!
    s.replaceAll(Pattern.quote("path\\to\\file"), "/new"); // Literal
    
  2. Replacement with $:
    "price: $100".replaceAll("\\$100", "$200"); // $2 β€” backreference, error!
    "price: $100".replaceAll("\\$100", Matcher.quoteReplacement("$200")); // OK
    
  3. Empty replacement:
    "abcabc".replace("b", ""); // "acac"
    "abcabc".replaceAll("b", ""); // "acac"
    
  4. No match:
    "hello".replace("x", "y"); // "hello" β€” unchanged, new object!
    

Production Experience

Scenario: User input sanitization:

// BAD β€” user entered "user[admin]" β†’ regex syntax error
String sanitized = input.replaceAll(userInput, "[REDACTED]");

// GOOD β€” literal replacement
String sanitized = input.replace(userInput, "[REDACTED]");

// OR β€” escaping
String sanitized = input.replaceAll(Pattern.quote(userInput), "[REDACTED]");

Scenario 2: Log masking (100K log lines/sec):

  • replaceAll("\\b\\d{4}\\b", "XXXX") for PIN masking β†’ ~300ms per 100K
  • Pre-compiled pattern β†’ ~80ms
  • Manual parsing β†’ ~15ms (but harder to maintain)

Best Practices for Highload

  • Default: replace() for literal text β€” safer and faster
  • For regex: pre-compiled Pattern + matcher.replaceAll()
  • For special characters in replacement: Matcher.quoteReplacement()
  • For ultra-low-latency: manual implementation via indexOf + StringBuilder
  • Security: always Pattern.quote() for user input in regex

🎯 Interview Cheat Sheet

Must know:

  • replace() β€” literal replacement (not regex), replaces ALL occurrences
  • replaceAll() β€” replacement by regular expression, replaces ALL occurrences
  • replaceFirst() β€” replacement by regex, only first match
  • Name replace is misleading β€” it replaces all, not one occurrence
  • Special characters in replacement for replaceAll: $1, $2 β€” backreference to groups
  • For literal $ in replacement: Matcher.quoteReplacement("$")

Frequent follow-up questions:

  • Why does replaceAll(".", "/") replace everything? β€” Dot in regex = β€œany character”. Use replace(".", "/") for literal replacement.
  • What’s faster: replace() or replaceAll()? β€” replace() is faster β€” no regex overhead. replace('a','b') β€” direct array pass.
  • Does replace() change only the first occurrence? β€” No, despite the name, replace() changes ALL occurrences.
  • How to replace only the first occurrence of text? β€” replaceFirst() β€” but this is regex. For literal β€” indexOf + substring.

Red flags (DON’T say):

  • ❌ β€œreplace() changes only the first occurrence” β€” changes ALL, despite the name
  • ❌ β€œreplaceAll() is faster than replace()” β€” opposite, regex is slower
  • ❌ β€œYou can pass user input directly to replaceAll()” β€” regex injection, use Pattern.quote()
  • ❌ β€œ$ in replacement β€” just a symbol” β€” it’s a backreference to regex groups

Related topics:

  • [[15. How split() Method Works]]
  • [[7. What Happens When Concatenating Strings with + Operator]]
  • [[4. Why String is Immutable]]