Java
String Split Method
Empty Values
Programming
Data Handling

Java String split removed empty values

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Java's String.split() does not remove all empty values. It specifically removes trailing empty strings from the result array when you use the default one-argument form. Empty strings in the middle of the input are preserved. To keep trailing empty values, pass -1 as the second argument: split(delimiter, -1).

java
1String input = "a,b,,";
2
3String[] defaultSplit = input.split(",");
4// Result: ["a", "b"]  -- trailing empties dropped
5
6String[] keepAll = input.split(",", -1);
7// Result: ["a", "b", "", ""]  -- trailing empties preserved

This behavior catches many developers off guard, especially when parsing delimited data where empty fields carry meaning.

How the Limit Parameter Works

The split method has two overloads:

java
String[] split(String regex)
String[] split(String regex, int limit)

The one-argument form behaves as if you passed limit = 0. The limit parameter controls two things: how many times the pattern is applied, and whether trailing empty strings are included.

Limit ValuePattern ApplicationsTrailing Empty Strings
0 (default)UnlimitedRemoved
-1UnlimitedPreserved
n > 0At most n - 1 timesPreserved

Default behavior (limit = 0)

java
"a,b,,".split(",")
// Splits into: ["a", "b", "", ""]
// Trailing empties removed: ["a", "b"]

Negative limit (limit = -1)

java
"a,b,,".split(",", -1)
// Splits into: ["a", "b", "", ""]
// Trailing empties preserved: ["a", "b", "", ""]

Positive limit (limit = 3)

java
"a,b,c,d".split(",", 3)
// Splits at most 2 times: ["a", "b", "c,d"]
// The remainder stays in the last element

Middle Empty Values Are Always Preserved

A critical detail: only trailing empty strings are affected by the default limit. Empty strings between non-empty values survive regardless.

java
1"a,,b".split(",")
2// Result: ["a", "", "b"]  -- middle empty preserved
3
4"a,,b,,".split(",")
5// Result: ["a", "", "b"]  -- middle empty preserved, trailing empties dropped

This asymmetry is the root of most confusion. Developers expect consistent behavior for all empty fields, but the spec only drops trailing ones.

The Delimiter Is a Regular Expression

Another common source of bugs is forgetting that split() treats its first argument as a regular expression, not a plain string. Characters with special meaning in regex must be escaped.

java
1// WRONG: "." matches any character
2"api.v1.example".split(".")
3// Result: []  -- splits on every character, all trailing empties removed
4
5// CORRECT: escape the dot
6"api.v1.example".split("\\.")
7// Result: ["api", "v1", "example"]

Characters that need escaping in regex: ., |, *, +, ?, (, ), [, ], {, }, ^, $, \.

Use Pattern.quote for Dynamic Delimiters

When the delimiter comes from user input or configuration, hand-escaping is error-prone. Use Pattern.quote() to treat any string as a literal:

java
1import java.util.regex.Pattern;
2
3String delimiter = "|";  // pipe is a regex alternation operator
4String input = "a|b|c";
5
6// WRONG: splits on empty string alternation
7String[] wrong = input.split(delimiter);
8
9// CORRECT: treats "|" as a literal character
10String[] correct = input.split(Pattern.quote(delimiter), -1);
11// Result: ["a", "b", "c"]

Real-World Scenarios

Parsing CSV-like Data

When processing pipe-delimited or tab-delimited export files, trailing empty fields represent real data (for example, a nullable column with no value). Using the default split drops those fields and shifts all subsequent column indices.

java
1// TSV row with empty last field (nullable column)
2String row = "John\tDoe\t30\t";
3
4String[] defaultParts = row.split("\t");
5// Result: ["John", "Doe", "30"]  -- 3 fields, lost the empty 4th
6
7String[] allParts = row.split("\t", -1);
8// Result: ["John", "Doe", "30", ""]  -- 4 fields, correct

Processing Configuration Values

java
1String config = "host=db.example.com=extra";
2
3// Limit to 2 to keep everything after the first "=" together
4String[] parts = config.split("=", 2);
5// Result: ["host", "db.example.com=extra"]

Using a positive limit here prevents the split from breaking on the second = sign, which is part of the value.

Counting Occurrences

java
1// Count how many segments a path has
2String path = "/usr/local/bin/";
3int segments = path.split("/", -1).length;
4// Result: 5 (["", "usr", "local", "bin", ""])
5// Without -1: 4 (trailing empty dropped)

Comparison: split vs. StringTokenizer vs. Guava Splitter

FeatureString.split()StringTokenizerGuava Splitter
Trailing emptiesDropped by defaultAlways droppedConfigurable
Regex supportYesNoOptional
Empty token handlingMiddle preservedAlways droppedConfigurable
Return typeString[]EnumerationIterable<String>
Thread-safeYes (immutable)NoYes (immutable)

If you need full control over empty value handling, Guava's Splitter is the most explicit API:

java
1import com.google.common.base.Splitter;
2
3List<String> parts = Splitter.on(',')
4    .splitToList("a,b,,");
5// Result: ["a", "b", "", ""]
6
7List<String> trimmed = Splitter.on(',')
8    .omitEmptyStrings()
9    .trimResults()
10    .splitToList("a, b, , ");
11// Result: ["a", "b"]

When to Use split vs. a Real Parser

String.split() works for simple delimited data where fields never contain the delimiter character. It breaks down when the format supports quoting or escaping.

java
1// This CSV line has a quoted field containing a comma
2String csvLine = "\"Smith, John\",42,Engineer";
3
4// split on comma breaks the quoted field
5String[] parts = csvLine.split(",");
6// Result: ["\"Smith", " John\"", "42", "Engineer"]  -- wrong

For CSV, TSV with quoting, or any structured text format, use a dedicated parser like OpenCSV, Apache Commons CSV, or Jackson CSV. split() is not a format parser.

Common Pitfalls

Assuming all empty values are removed is the most common mistake. Only trailing empty strings are discarded by the default one-argument form. Middle empties survive.

Forgetting that the delimiter is a regex causes silent bugs. Splitting on . without escaping matches every character and produces an empty array (all elements are trailing empties that get removed).

Using split(",") for CSV data and expecting it to handle quoted commas, escaped delimiters, or multiline fields leads to broken parsing. Use a real CSV library.

Relying on the default limit when field count matters produces arrays with fewer elements than expected, causing ArrayIndexOutOfBoundsException downstream when code accesses fields by position.

Using split(delimiter, -1) on user input without validating the result length can introduce injection risks if the code assumes a fixed number of fields.

Summary

  • String.split() removes trailing empty strings by default because it uses a limit of 0.
  • Empty strings in the middle of the input are always preserved.
  • Pass -1 as the second argument to keep all trailing empty fields.
  • The delimiter is a regex. Escape special characters or use Pattern.quote().
  • Use a positive limit (split("=", 2)) to control the maximum number of splits.
  • For structured formats with quoting or escaping, use a dedicated parser instead of split().

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.