Apache Commons: Practical Guide to Essential Utilities
Hands-on Java examples for Apache Commons Lang3, IO, Collections4, Text, Codec, and Validator—covering the utilities developers reach for most in real projects.

Apache Commons: Practical Guide to Essential Utilities
Apache Commons libraries are battle-tested and widely adopted, yet many teams only scratch the surface.
This guide provides practical real-world examples for the classes you'll actually use: string cleanup, numeric parsing, file I/O, encoding, advanced collections, templating, and validation. Each example is ready to run—just adapt variable names to your domain.
Dependencies (Gradle)
dependencies {
implementation 'org.apache.commons:commons-lang3:3.20.0'
implementation 'commons-io:commons-io:2.21.0'
implementation 'org.apache.commons:commons-collections4:4.5.0'
implementation 'org.apache.commons:commons-text:1.15.0'
implementation 'commons-codec:commons-codec:1.21.0'
implementation 'commons-validator:commons-validator:1.10.1'
}1) Apache Commons Lang 3
StringUtils — Safe String Operations
Use this snippet for common null-safe string cleanup, checks, and formatting helpers.
import org.apache.commons.lang3.StringUtils;
String rawName = " Alice Smith ";
String rawComment = " ";
String role = "ADMIN";
// Normalize spaces
String normalized = StringUtils.normalizeSpace(rawName); // "Alice Smith"
// Default if blank
String comment = StringUtils.defaultIfBlank(rawComment, "No comment"); // "No comment"
// Null-safe comparison
boolean same = StringUtils.equalsIgnoreCase("admin", role); // true
// Validate multiple inputs
boolean missing = StringUtils.isAnyBlank("Alice", "", "London"); // true
// Abbreviate text
String preview = StringUtils.abbreviate(
"Apache Commons makes Java code cleaner.", 24);
// "Apache Commons makes..."
// Join
String csv = StringUtils.join(new String[]{"lang3", "io", "text"}, ", "); // "lang3, io, text"
// Padding
String padded = StringUtils.leftPad("42", 6, '0'); // "000042"
// Repeat
String repeated = StringUtils.repeat("ab", 3); // "ababab"
// Count matches
int count = StringUtils.countMatches("hello world hello", "hello"); // 2
// Reverse
String reversed = StringUtils.reverse("Apache"); // "ehcapA"ObjectUtils — Null-Safe Fallbacks
ObjectUtils provides null-safe fallback helpers for working with objects and values.
import org.apache.commons.lang3.ObjectUtils;
String nickName = null;
String fullName = "Alice";
// Pick first non-null display value
String displayName = ObjectUtils.firstNonNull(nickName, fullName, "Anonymous"); // "Alice"
// Fallback when value is null
String region = ObjectUtils.defaultIfNull(null, "ap-south-1"); // "ap-south-1"
// Validate that multiple values are non-null
boolean ready = ObjectUtils.allNotNull(displayName, region); // true
// Null-safe equality
boolean same = ObjectUtils.equals(null, null);
// true
// Pick maximum value (null-safe)
Integer max = ObjectUtils.max(10, 3, 25, 7);
// 25NumberUtils — Safe Parsing and Numeric Checks
NumberUtils handles safe parsing, numeric checks, and min/max calculations.
import org.apache.commons.lang3.NumberUtils;
// Parse int with default value
int retries = NumberUtils.toInt("5", 3); // 5
// Check whether value is a valid number
boolean isNum = NumberUtils.isCreatable("12x"); // false
// Pick max value
long maxLatency = NumberUtils.max(120L, 450L, 310L); // 450
// Pick min value
double minScore = NumberUtils.min(8.5, 3.2, 6.7); // 3.2BooleanUtils — Nullable & String Booleans
BooleanUtils makes nullable booleans and custom string-to-boolean mappings easy to handle.
import org.apache.commons.lang3.*;
Boolean enabledFlag = null;
// Convert nullable Boolean to primitive with default
boolean enabled = BooleanUtils.toBooleanDefaultIfNull(enabledFlag, false); // false
// Map custom text values to Boolean
Boolean approved = BooleanUtils.toBooleanObject("Y", "Y", "N", null); // true
// Map rejection value
Boolean rejected = BooleanUtils.toBooleanObject("N", "Y", "N", null); // false
// Convert boolean to yes/no text
String label = BooleanUtils.toStringYesNo(true); // "yes"
// Convert boolean to 1/0
int asInt = BooleanUtils.toInteger(true); // 1
// Check true safely
boolean isTrue = BooleanUtils.isTrue(Boolean.TRUE);
// true
// Convert "yes", "true", "on", "y", or "t" string to boolean true
boolean active = BooleanUtils.toBoolean("yes"); // trueCharUtils — Character Parsing Helpers
CharUtils helps with character conversions and checks.
import org.apache.commons.lang3.CharUtils;
// Convert numeric character to int
int digit = CharUtils.toIntValue('7'); // 7
// Check if character is printable ASCII
boolean isPrintable = CharUtils.isAsciiPrintable('A'); // true
// Convert char to String
String charStr = CharUtils.toString('|'); // "|"SystemUtils — OS and JVM Runtime Info
SystemUtils exposes OS and JVM runtime metadata.
import org.apache.commons.lang3.SystemUtils;
boolean isWindows = SystemUtils.IS_OS_WINDOWS;
boolean isLinux = SystemUtils.IS_OS_LINUX;
String javaVersion = SystemUtils.JAVA_VERSION; // e.g. "21.0.3"
String userHome = SystemUtils.USER_HOME; // e.g. "/home/alice"
String javaHome = SystemUtils.JAVA_HOME; // e.g. "/usr/lib/jvm/java-21"2) Apache Commons IO
FileUtils — Read, Write, Copy, Delete
FileUtils simplifies common file and directory operations such as read, write, copy, list, and size checks.
import org.apache.commons.io.*;
import java.io.*;
import java.nio.charset.StandardCharsets;
File config = new File("config/app.properties");
// Read full file as UTF-8 text
String content = FileUtils.readFileToString(config, StandardCharsets.UTF_8); // "app.name=myapp\napp.version=1.0"
File backup = new File("backup/app.properties");
// Copy file to backup location
FileUtils.copyFile(config, backup);
File output = new File("output/summary.txt");
// Write transformed content to output file
FileUtils.writeStringToFile(output, content.toUpperCase(), StandardCharsets.UTF_8);
FileUtils.deleteQuietly(output); // No exception if file is missing
// List all .log files recursively
Collection<File> logs = FileUtils.listFiles(
new File("var/logs"),
new String[] {"log"},
true
);
// Get total directory size in bytes
long sizeBytes = FileUtils.sizeOfDirectory(new File("var/logs")); // e.g. 102400IOUtils — Streams Made Easy
IOUtils reduces stream boilerplate for converting, reading lines, and copying bytes.
import org.apache.commons.io.*;
import java.io.*;
import java.nio.charset.StandardCharsets;
// Stream → String
try (InputStream input = new ByteArrayInputStream(
"line-1\nline-2".getBytes(StandardCharsets.UTF_8))) {
// Convert stream content into String
String payload = IOUtils.toString(input, StandardCharsets.UTF_8); // "line-1\nline-2"
}
// Stream → List of lines
try (InputStream input = new FileInputStream("data/records.csv")) {
// Read stream as list of lines
List<String> lines = IOUtils.readLines(input, StandardCharsets.UTF_8);
// ["header,row", "alice,30", "bob,25"]
}
// Copy one stream to another
try (InputStream in = new FileInputStream("source.bin");
OutputStream out = new FileOutputStream("target.bin")) {
// Copy bytes from input stream to output stream
long bytesCopied = IOUtils.copy(in, out);
// Returns number of bytes copied
}3) Apache Commons Collections 4
Bag — Count Duplicate Items
Bag stores elements with occurrence counts, which is useful for frequency analysis.
import org.apache.commons.collections4.*;
import org.apache.commons.collections4.bag.*;
import java.util.*;
Bag<String> errorCodes = new HashBag<>();
// Add item with count in one call
errorCodes.add("DB_TIMEOUT", 3);
// Add duplicate values normally
errorCodes.add("BAD_REQUEST");
errorCodes.add("BAD_REQUEST");
// Get frequency for a specific value
int timeoutCount = errorCodes.getCount("DB_TIMEOUT"); // 3
// Get frequency for another value
int badReqCount = errorCodes.getCount("BAD_REQUEST"); // 2
// Get unique values without duplicates
Set<String> unique = errorCodes.uniqueSet(); // {"DB_TIMEOUT", "BAD_REQUEST"}BidiMap — Two-Way Lookup
BidiMap supports lookup in both directions: key to value and value to key.
import org.apache.commons.collections4.*;
import org.apache.commons.collections4.bidimap.*;
BidiMap<Integer, String> httpCodes = new DualHashBidiMap<>();
// Add code to label mappings
httpCodes.put(200, "OK");
httpCodes.put(201, "CREATED");
httpCodes.put(404, "NOT_FOUND");
// Regular map-style lookup
String label = httpCodes.get(404); // "NOT_FOUND"
// Reverse lookup by value
Integer code = httpCodes.getKey("CREATED"); // 201MultiValuedMap — One Key, Many Values
MultiValuedMap allows multiple values per key, ideal for headers, params, and tags.
import org.apache.commons.collections4.*;
import org.apache.commons.collections4.multimap.*;
import java.util.*;
MultiValuedMap<String, String> headers = new ArrayListValuedHashMap<>();
// Add multiple values under same key
headers.put("Cache-Control", "no-cache");
headers.put("Cache-Control", "no-store");
headers.put("Accept", "application/json");
// Read all values for one key
Collection<String> cacheVals = headers.get("Cache-Control"); // ["no-cache", "no-store"]
// Count total key-value entries
int totalEntries = headers.size(); // 3MultiSet & CircularFifoQueue
MultiSet tracks counted elements, and CircularFifoQueue keeps a fixed-size rolling window.
import org.apache.commons.collections4.*;
import org.apache.commons.collections4.multiset.*;
import org.apache.commons.collections4.queue.*;
MultiSet<String> tags = new HashMultiSet<>();
// Add values with explicit counts
tags.add("java", 5);
tags.add("spring", 3);
tags.add("apache-commons");
// Count occurrences of a value
int javaCount = tags.getCount("java"); // 5
// Total entries including duplicates
int totalTags = tags.size(); // 9 (5 + 3 + 1)
// Rolling window: keeps only the last N items
CircularFifoQueue<String> recentEvents = new CircularFifoQueue<>(3);
recentEvents.add("user.login");
recentEvents.add("order.placed");
recentEvents.add("payment.success");
recentEvents.add("shipment.created"); // "user.login" is removed
System.out.println(recentEvents);
// [order.placed, payment.success, shipment.created]CollectionUtils & MapUtils — Safe Operations
CollectionUtils offers set-style collection operations, and MapUtils provides null-safe typed map reads.
import org.apache.commons.collections4.*;
import java.util.*;
List<String> allowed = List.of("ADMIN", "AUTHOR", "READER");
List<String> requested = List.of("AUTHOR", "READER");
// Check if requested values are fully allowed
boolean permitted = CollectionUtils.isSubCollection(requested, allowed); // true
Collection<String> merged = CollectionUtils.union(
List.of("java", "spring"),
List.of("spring", "apache-commons")
);
// [java, spring, apache-commons]
Collection<String> common = CollectionUtils.intersection(
List.of("java", "spring", "kafka"),
List.of("spring", "kafka", "redis")
);
// [spring, kafka]import org.apache.commons.collections4.*;
import java.util.*;
Map<String, Object> config = Map.of(
"timeout", 30,
"region", "ap-south-1",
"retries", "5"
);
// Read int with fallback
int timeout = MapUtils.getIntValue(config, "timeout", 10); // 30
// Read String with fallback
String region = MapUtils.getString(config, "region", "us-east-1"); // "ap-south-1"
// Null-safe empty check
boolean isEmpty = MapUtils.isEmpty(config); // false4) Apache Commons Text
WordUtils & StringEscapeUtils
WordUtils helps with title formatting and wrapping, while StringEscapeUtils handles safe escaping.
import org.apache.commons.text.*;
// Convert sentence to title case
String title = WordUtils.capitalizeFully("apache commons text utilities"); // "Apache Commons Text Utilities"
String wrapped = WordUtils.wrap(
"Apache Commons Text provides utilities for working with Strings.",
30
);
// Multi-line string, each line max 30 chars:
// "Apache Commons Text provides\nutilities for working with\nStrings."
String html = "<div>Hello <b>Alice</b> & <i>Bob</i></div>";
// Escape unsafe HTML characters
String escaped = StringEscapeUtils.escapeHtml4(html); // "<div>Hello <b>Alice</b> & <i>Bob</i></div>"
// Convert escaped text back to original
String restored = StringEscapeUtils.unescapeHtml4(escaped); // "<div>Hello <b>Alice</b> & <i>Bob</i></div>"StringSubstitutor — Template Replacement
StringSubstitutor replaces template placeholders with runtime values for readable message generation.
import org.apache.commons.text.*;
import java.util.*;
// Notification email template
String template =
"Hi ${name},\n" +
"Your order ${orderId} worth ${amount} is ${status}.\n" +
"Expected delivery: ${deliveryDate}";
String message = StringSubstitutor.replace(template, Map.of(
"name", "Alice",
"orderId", "ORD-1024",
"amount", "$89.99",
"status", "DISPATCHED",
"deliveryDate", "2026-04-02"
));
// "Hi Alice,
// Your order ORD-1024 worth $89.99 is DISPATCHED.
// Expected delivery: 2026-04-02"RandomStringGenerator — Controlled Random Generation
RandomStringGenerator creates constrained random strings using allowed ranges and character predicates.
import org.apache.commons.text.*;
// Letters and digits only (no special chars)
RandomStringGenerator couponGen = RandomStringGenerator.builder()
.withinRange('0', 'z')
.filteredBy(CharacterPredicates.LETTERS, CharacterPredicates.DIGITS)
.build();
// Generate alphanumeric coupon code
String coupon = couponGen.generate(10);
// "aB3cDeFgHi" (random alphanumeric)
// Lowercase letters only — useful for slugs or tokens
RandomStringGenerator slugGen = RandomStringGenerator.builder()
.withinRange('a', 'z')
.build();
// Generate lowercase slug
String slug = slugGen.generate(8);
// "xtqmrwpj" (random lowercase)5) Apache Commons Codec
Base64 — Encode and Decode
Base64 handles byte-to-text encoding/decoding, including URL-safe variants.
import org.apache.commons.codec.binary.*;
import java.nio.charset.StandardCharsets;
String original = "user:secret-password";
// Encode text to Base64 bytes
byte[] encoded = Base64.encodeBase64(original.getBytes(StandardCharsets.UTF_8));
String encodedStr = new String(encoded); // "dXNlcjpzZWNyZXQtcGFzc3dvcmQ="
// Decode Base64 back to bytes/text
byte[] decoded = Base64.decodeBase64(encoded);
String decodedStr = new String(decoded, StandardCharsets.UTF_8); // "user:secret-password"
// URL-safe Base64 (no + or / characters)
byte[] urlSafe = Base64.encodeBase64URLSafe(original.getBytes(StandardCharsets.UTF_8));
// "dXNlcjpzZWNyZXQtcGFzc3dvcmQ" (no padding, safe in URLs and tokens)DigestUtils — File and String Checksums
DigestUtils computes MD5/SHA hashes for content integrity and change detection.
import org.apache.commons.codec.digest.*;
import java.io.*;
// Hash a string
String sha256 = DigestUtils.sha256Hex("apache-commons"); // "3c90f5b6e0c4e3f1a2b..." (64-char hex)
String md5 = DigestUtils.md5Hex("apache-commons"); // "d41d8cd98f00b204..." (32-char hex)
// Hash a file (useful for verifying downloads or detecting changes)
File jar = new File("libs/commons-lang3.jar");
String fileChecksum = DigestUtils.sha256Hex(new FileInputStream(jar)); // "a3f9c12e..." (checksum of the file)Hex — Binary to Hex Encoding
Hex converts binary data to hexadecimal text and decodes it back.
import org.apache.commons.codec.binary.*;
import java.nio.charset.StandardCharsets;
byte[] bytes = "hello".getBytes(StandardCharsets.UTF_8);
// Encode bytes to hex string
String hex = Hex.encodeHexString(bytes); // "68656c6c6f"
// Decode hex string back to bytes
byte[] decoded = Hex.decodeHex(hex);
String original = new String(decoded, StandardCharsets.UTF_8); // "hello"Soundex & Metaphone — Phonetic Matching
Soundex and Metaphone provide phonetic matching for fuzzy search and duplicate detection.
import org.apache.commons.codec.language.*;
Soundex soundex = new Soundex();
String codeAlice = soundex.encode("Alice"); // "A420"
String codeAlyssa = soundex.encode("Alyssa"); // "A420"
String codeBob = soundex.encode("Bob"); // "B100"
// Names with the same Soundex code sound alike
boolean soundsLike = soundex.encode("Smith").equals(soundex.encode("Smyth")); // true
Metaphone metaphone = new Metaphone();
boolean same = metaphone.isMetaphoneEqual("Thompson", "Thomson"); // true6) Apache Commons Validator
Email, URL, Domain, IP
Validator routines provide ready-to-use checks for email, URL, domain, and IP inputs.
import org.apache.commons.validator.routines.*;
boolean validEmail = EmailValidator.getInstance().isValid("alice@example.com"); // true
boolean invalidEmail = EmailValidator.getInstance().isValid("alice@"); // false
UrlValidator urlVal = new UrlValidator(new String[] {"http", "https"});
boolean validUrl = urlVal.isValid("https://example.com/api/v1"); // true
boolean invalidUrl = urlVal.isValid("ftp://example.com"); // false — ftp not in allowed schemes
boolean validIp = InetAddressValidator.getInstance().isValid("10.10.1.20"); // true
boolean validIpv6 = InetAddressValidator.getInstance().isValid("2001:db8::1"); // true
boolean validDomain = DomainValidator.getInstance().isValid("example.com"); // true
boolean invalidDomain = DomainValidator.getInstance().isValid("not_a_domain"); // falseCredit Card & Date Validation
CreditCardValidator and DateValidator validate payment card formats and strict date patterns.
import org.apache.commons.validator.routines.*;
import java.util.Date;
// Default validates VISA, MASTERCARD, AMEX, DISCOVER
CreditCardValidator ccValidator = new CreditCardValidator();
boolean validCard = ccValidator.isValid("4111111111111111"); // true (VISA test number)
boolean invalidCard = ccValidator.isValid("1234567890123456"); // false
// AMEX + VISA only
CreditCardValidator strictValidator = new CreditCardValidator(
CreditCardValidator.AMEX + CreditCardValidator.VISA
);
boolean onlyVisa = strictValidator.isValid("4111111111111111"); // true
DateValidator dateVal = new DateValidator();
boolean validDate = dateVal.isValid("2026-03-28", "yyyy-MM-dd"); // true
boolean invalidDate = dateVal.isValid("2026-13-01", "yyyy-MM-dd"); // false (month 13)
Date parsed = dateVal.validate("2026-03-28", "yyyy-MM-dd"); // Date object for 2026-03-28Custom Code Validation
CodeValidator enforces custom business code formats using regex and length constraints.
import org.apache.commons.validator.routines.*;
// Employee code: must match EMP-XXXX and be exactly 8 chars
CodeValidator empCodeVal = new CodeValidator("EMP-\\d{4}", 8, null);
boolean valid = empCodeVal.isValid("EMP-1024"); // true
boolean invalid = empCodeVal.isValid("EMP-99"); // false (too short)
// Ticket code: TKT- followed by 6 digits
CodeValidator ticketVal = new CodeValidator("TKT-\\d{6}", 10, null);
boolean validTicket = ticketVal.isValid("TKT-482931"); // trueCombined Input Validation
This combined validator flow shows how to gate a payload using multiple routine validators.
import org.apache.commons.validator.routines.*;
String email = "alice@example.com";
String website = "https://example.com";
String serverIp = "192.168.1.10";
String invoiceDt = "2026-03-28";
String empCode = "EMP-2048";
boolean allValid =
EmailValidator.getInstance().isValid(email)
&& new UrlValidator(new String[] {"http", "https"}).isValid(website)
&& InetAddressValidator.getInstance().isValid(serverIp)
&& DomainValidator.getInstance().isValid("example.com")
&& new CreditCardValidator().isValid("4111111111111111")
&& new DateValidator().isValid(invoiceDt, "yyyy-MM-dd")
&& new CodeValidator("EMP-\\d{4}", 8, null).isValid(empCode);
// true — if all checks passBest Practices
- Use JDK APIs first; adopt Commons only when it saves real boilerplate.
- Wrap domain-specific validations in your own helper classes for clarity.
- Wrap
DigestUtilscalls in a service; keep hashing logic in one place. - Don't use random string utilities for cryptographic secrets — use
SecureRandom. - Update dependencies regularly for security patches.
Summary
Apache Commons eliminates boilerplate across six key areas:
| Library | Best Used For |
|---|---|
| Lang3 | String cleanup, safe parsing, null-safe fallbacks, system info |
| IO | File read/write/copy, stream-to-string, directory listing |
| Collections4 | Frequency counting, bidirectional maps, multi-value maps, rolling queues |
| Text | HTML escaping, template substitution, controlled random generation |
| Codec | Base64, hex, file checksums, phonetic name matching |
| Validator | Email, URL, IP, domain, credit card, date, custom code validation |
Start with Lang3 and Validator—they cover the majority of common utility needs. Add IO, Codec, and Collections4 as your use cases grow.
Did you find this article useful?