Difference Between replace() vs replaceAll()
Both methods replace all found occurrences. The difference is how they search:
π’ 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
-
Mistake:
replaceAll("user.name", "admin")β dot = any character Solution:replaceAll(Pattern.quote("user.name"), "admin")orreplace("user.name", "admin") -
Mistake: Thinking
replacechanges only the first one Solution:replacechanges ALL. For first βreplaceFirst -
Mistake:
$in replacement string forreplaceAllSolution:$1,$2β group references. For literal$useMatcher.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
- Regex metacharacters in replaceAll:
s.replaceAll("path\\to\\file", "/new"); // \t = tab, \f = form feed! s.replaceAll(Pattern.quote("path\\to\\file"), "/new"); // Literal - Replacement with
$:"price: $100".replaceAll("\\$100", "$200"); // $2 β backreference, error! "price: $100".replaceAll("\\$100", Matcher.quoteReplacement("$200")); // OK - Empty replacement:
"abcabc".replace("b", ""); // "acac" "abcabc".replaceAll("b", ""); // "acac" - 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 occurrencesreplaceAll()β replacement by regular expression, replaces ALL occurrencesreplaceFirst()β replacement by regex, only first match- Name
replaceis 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β. Usereplace(".", "/")for literal replacement. - Whatβs faster:
replace()orreplaceAll()? β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 thanreplace()β β opposite, regex is slower - β βYou can pass user input directly to
replaceAll()β β regex injection, usePattern.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]]