Remove Extra Spaces from a String in Java
Problem
Extra spaces are the leading, trailing, and repeated spaces that can creep into text — collapsing them down to single spaces between words is called normalizing whitespace.
Given a string, remove its leading and trailing spaces, and collapse every run of spaces between words down to one.
Java Program
public class RemoveExtraSpaces {
public static void main(String[] args) {
String str = " Java is fun ";
String trimmed = str.trim();
StringBuilder result = new StringBuilder();
boolean lastWasSpace = false;
for (char c : trimmed.toCharArray()) {
if (c == ' ') {
if (!lastWasSpace) result.append(c); // only the first space in a run gets through
lastWasSpace = true;
} else {
result.append(c);
lastWasSpace = false;
}
}
System.out.println(result.toString());
}
}Output
Core Logic
Trimming the ends first, then tracking whether the previous character was already a space, lets a single pass collapse every run of spaces down to one.
- 1
str.trim()removes any leading or trailing spaces before the scan begins. - 2A boolean
lastWasSpaceflag tracks whether the previous character appended was a space. - 3For a space character, it's only appended if
lastWasSpaceisfalse— the first space in a run gets through, later ones in the same run are skipped. - 4For any other character, it's always appended, and
lastWasSpaceis reset tofalse.
" Java is fun ", trimming first removes the outer spaces, then the runs of three spaces between words each collapse down to one, producing "Java is fun".Key Point: Trimming has to happen before the scan, not after — trimming a string that still has internal double spaces wouldn't touch those, since trim() only strips from the very start and end.
Why: Each character is visited once, and the result buffer holds the normalized string, whose length is at most the original's.
Key Concepts
Approach 2: Regex Replace
public class RemoveExtraSpacesRegex {
public static void main(String[] args) {
String str = " Java is fun ";
// Trims the ends, then collapses every run of spaces down to one
String result = str.trim().replaceAll(" +", " ");
System.out.println(result);
}
}
Output
Core Logic
A single regex can express 'one or more spaces' directly, replacing every run with exactly one space in one call.
- 1
str.trim()removes the leading and trailing spaces first, same as the manual version. - 2
.replaceAll(" +", " ")matches every run of one or more spaces and replaces each run with a single space. - 3Runs of just one space match too, but replacing a single space with a single space leaves it unchanged.
" Java is fun " gives "Java is fun", and replaceAll(" +", " ") then collapses each triple-space run down to one, producing "Java is fun".Key Point: " +" only matches the literal space character — "\\s+" would be the version to reach for if tabs or newlines also needed collapsing.
Why: trim() and replaceAll() each build a new string, so the final result string is what the extra space is spent on.
Key Concepts
Approach 3: Java 8
import java.util.Arrays;
import java.util.stream.Collectors;
public class RemoveExtraSpacesStream {
public static void main(String[] args) {
String str = " Java is fun ";
// Splitting on space runs removes them; joining puts back exactly one
String result = Arrays.stream(str.trim().split(" +"))
.collect(Collectors.joining(" "));
System.out.println(result);
}
}
Output
Core Logic
Splitting the trimmed string on runs of spaces produces exactly the individual words, so joining them back with single spaces rebuilds the string with every run collapsed.
- 1
str.trim()removes the leading and trailing spaces first, same as the other two approaches. - 2
.split(" +")splits on every run of one or more spaces, producing an array of just the words — the runs themselves never appear in the output. - 3
Arrays.stream(...)turns that array into aStream<String>. - 4
.collect(Collectors.joining(" "))rejoins the words with exactly one space between each, regardless of how many spaces originally separated them.
" Java is fun " gives "Java is fun", which splits into ["Java", "is", "fun"] and joins back as "Java is fun".Key Point: This sidesteps run-collapsing entirely — instead of detecting and skipping repeated spaces, splitting removes them completely and joining() puts back exactly the separator that's wanted.
Why: split() scans the whole string once to build the word array, and joining() builds a new string holding those words with single-space separators.