What Is Guava's CharMatcher? A Complete Guide to Character Matching in Java

Guava's CharMatcher is an abstract class in com.google.common.base that provides high-performance character matching and string manipulation for BMP Unicode characters, functioning like a Predicate<Character> optimized for primitive char values.

When processing text in Java, developers often need efficient ways to filter, validate, or transform strings based on character types. The CharMatcher class in the Google Guava library (google/guava) solves this by offering a flexible API that operates directly on primitive char values, avoiding the boxing overhead of Character objects while providing a rich set of text-processing utilities.

Core Architecture and Design Patterns

The Abstract Matching Contract

At the foundation of the API lies a single abstract method that defines the matching logic. In guava/src/com/google/common/base/CharMatcher.java (lines 66-68), the contract is specified as:

public abstract boolean matches(char c);

Subclasses implement this method to determine whether a given character satisfies the matcher condition. This design allows CharMatcher to function similarly to Predicate<Character> but with significantly better performance characteristics due to primitive specialization.

Static Factory Methods

Rather than requiring developers to subclass CharMatcher directly, the class exposes numerous static factory methods (lines 112-182) for common use cases:

  • any() and none() — match all or no characters
  • whitespace() — matches Unicode whitespace
  • ascii() — matches ASCII characters (0-127)
  • digit() — matches Unicode digits
  • javaLetterOrDigit() — matches letters or digits according to Java's Character class
  • inRange(char start, char end) — matches characters within a range
  • anyOf(CharSequence chars) and noneOf(CharSequence chars) — match any or none of a specific set

Precomputation for Performance

For matchers used repeatedly in tight loops, the precomputed() method (lines 100-104) constructs an optimized implementation. According to the source code, this method builds a fast matcher using either a BitSet or a small hash table, significantly reducing the runtime cost of character classification operations.

Combinatorial Logic

Lines 71-84 implement set-style composition operations that allow building complex matchers from simple ones:

  • and(CharMatcher other) — matches characters that satisfy both matchers
  • or(CharMatcher other) — matches characters that satisfy either matcher
  • negate() — matches characters that the original matcher rejects

These methods return new CharMatcher instances without modifying the originals, enabling immutable, thread-safe composition chains.

String Processing Capabilities

Beyond single-character testing, CharMatcher provides bulk text manipulation methods (lines 84-124) that operate on entire strings:

  • removeFrom(CharSequence sequence) — deletes all matching characters
  • retainFrom(CharSequence sequence) — keeps only matching characters
  • replaceFrom(CharSequence sequence, char replacement) — substitutes matching characters
  • trimFrom(CharSequence sequence) — removes leading and trailing matches
  • collapseFrom(CharSequence sequence, char replacement) — replaces consecutive matching characters with a single replacement
  • trimAndCollapseFrom(CharSequence sequence, char replacement) — combines trimming and collapsing operations

Unicode Limitations and BMP Handling

An important architectural constraint documented in lines 38-45 is that CharMatcher operates exclusively on BMP (Basic Multilingual Plane) characters. Supplementary Unicode characters (those outside the BMP, with code points above U+FFFF) are treated as surrogate pairs—two separate char values. This means CharMatcher processes each surrogate half individually rather than as a single logical character.

Practical Usage Examples

The following examples demonstrate common CharMatcher patterns using the factories and methods defined in the Guava source:

// 1. Trim whitespace (including Unicode whitespace) from a string
String raw = "\u2002\u3000 Hello Guava! \n";
String trimmed = CharMatcher.whitespace().trimFrom(raw);
// trimmed → "Hello Guava!"
// 2. Remove all non‑ASCII characters
String mixed = "Café naïve résumé – 123";
String asciiOnly = CharMatcher.ascii().retainFrom(mixed);
// asciiOnly → "C  123"
// 3. Collapse repeated punctuation
String noisy = "Wow!!!   Such...   Amazing!!!";
String collapsed = CharMatcher.is('.')
    .or(CharMatcher.is('!'))
    .collapseFrom(noisy, '-');
// collapsed → "Wow- Such- Amazing-"
// 4. Validate that a string contains only digits (BMP digits)
boolean onlyDigits = CharMatcher.digit().matchesAllOf("0123456789");
// onlyDigits → true
// 5. Combine matchers: keep only letters or digits
CharMatcher alnum = CharMatcher.javaLetterOrDigit();
String cleaned = alnum.retainFrom("User_@#42!");
// cleaned → "User42"

Implementation Files and Source Structure

The CharMatcher implementation spans several files within the Guava repository:

Lines 126-150 define specialized subclasses including FastMatcher, NamedFastMatcher, Any, None, Ascii, and Whitespace that provide optimized implementations for frequently used matching rules.

Summary

  • CharMatcher is an abstract class in com.google.common.base optimized for primitive char processing
  • Subclasses implement the matches(char c) method (lines 66-68) to define custom character classification logic
  • Static factories (lines 112-182) provide instant matchers for common patterns like whitespace, ASCII, and digits
  • The precomputed() method (lines 100-104) creates high-performance matchers using BitSet or hash tables
  • Combinator methods and(), or(), and negate() (lines 71-84) enable immutable matcher composition
  • Text-processing methods like trimFrom(), retainFrom(), and collapseFrom() provide bulk string manipulation
  • The API handles only BMP characters; supplementary Unicode code points are processed as surrogate pairs (lines 38-45)

Frequently Asked Questions

What is the difference between CharMatcher and Java's Predicate?

While both define boolean conditions on characters, CharMatcher operates on primitive char values avoiding autoboxing overhead, whereas Predicate<Character> requires Character objects. Additionally, CharMatcher provides specialized text-processing methods like trimFrom() and collapseFrom() that Predicate lacks, and supports precomputation optimizations for repeated matching operations.

How does CharMatcher handle Unicode characters beyond the BMP?

CharMatcher processes only BMP (Basic Multilingual Plane) characters. Supplementary characters—those with code points above U+FFFF—are represented as surrogate pairs in Java strings, and CharMatcher treats each surrogate as an individual char rather than a single logical character. This is documented in CharMatcher.java lines 38-45.

When should I use precomputed() on a CharMatcher?

Call precomputed() when you will use the same matcher repeatedly in performance-critical code. According to the source implementation (lines 100-104), this method builds a lookup table (using BitSet or SmallCharMatcher) that trades initialization time for significantly faster character classification during matching operations.

Which is faster: CharMatcher or regular expressions for simple character filtering?

For simple character class matching (such as removing all whitespace or digits), CharMatcher typically outperforms regular expressions because it avoids regex compilation overhead and can leverage precomputed lookup tables. The CharMatcherBenchmark.java file in the Guava test suite provides empirical performance comparisons between these approaches.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →