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.
Enjoyed this article?
Check out more articles or share this with your network.