Everything Java

← Back to blog

Published on Sat Feb 15 2025 10:00:00 GMT+0000 (Coordinated Universal Time) by Purusothaman Ramanujam

Object Utilities in Apache Commons Lang

Introduction

Working with objects in Java often involves handling null values, comparing objects safely, and providing default values. Apache Commons Lang’s ObjectUtils provides a comprehensive set of utilities that make object operations safer, more convenient, and more robust.

In this comprehensive guide, you’ll learn how to use ObjectUtils effectively with detailed examples and real-world use cases.

Adding Apache Commons Lang to Your Project

Maven Dependency

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.13.0</version>
</dependency>

Gradle Dependency

implementation 'org.apache.commons:commons-lang3:3.13.0'

Basic Object Operations

Null-Safe Operations

One of the biggest advantages of ObjectUtils is its null-safe operations:

import org.apache.commons.lang3.ObjectUtils;
public class ObjectUtilsBasics {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = null;
Integer num1 = 42;
Integer num2 = null;
// Null-safe default values
System.out.println(ObjectUtils.defaultIfNull(str1, "Default")); // "Hello"
System.out.println(ObjectUtils.defaultIfNull(str2, "Default")); // "Default"
System.out.println(ObjectUtils.defaultIfNull(num1, 0)); // 42
System.out.println(ObjectUtils.defaultIfNull(num2, 0)); // 0
// Null-safe first non-null value
System.out.println(ObjectUtils.firstNonNull(str1, str2, "Default")); // "Hello"
System.out.println(ObjectUtils.firstNonNull(str2, "Default", "Backup")); // "Default"
System.out.println(ObjectUtils.firstNonNull(null, null, "Last Resort")); // "Last Resort"
// Check if object is null
System.out.println(ObjectUtils.isEmpty(str1)); // false
System.out.println(ObjectUtils.isEmpty(str2)); // true
System.out.println(ObjectUtils.isEmpty("")); // true
System.out.println(ObjectUtils.isEmpty(" ")); // false (not empty, has whitespace)
}
}

Object Comparison

public class ObjectComparison {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = "Hello";
String str3 = "World";
String str4 = null;
// Null-safe equals
System.out.println(ObjectUtils.equals(str1, str2)); // true
System.out.println(ObjectUtils.equals(str1, str3)); // false
System.out.println(ObjectUtils.equals(str1, str4)); // false
System.out.println(ObjectUtils.equals(str4, str4)); // true (both null)
// Null-safe not equals
System.out.println(ObjectUtils.notEqual(str1, str2)); // false
System.out.println(ObjectUtils.notEqual(str1, str3)); // true
System.out.println(ObjectUtils.notEqual(str1, str4)); // true
// Compare with null safety
System.out.println(ObjectUtils.compare(str1, str2)); // 0 (equal)
System.out.println(ObjectUtils.compare(str1, str3)); // negative (str1 < str3)
System.out.println(ObjectUtils.compare(str3, str1)); // positive (str3 > str1)
System.out.println(ObjectUtils.compare(str1, str4)); // positive (non-null > null)
System.out.println(ObjectUtils.compare(str4, str1)); // negative (null < non-null)
}
}

Advanced Object Operations

Object Identity and Hash Code

public class ObjectIdentity {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = "Hello";
String str3 = new String("Hello");
String str4 = null;
// Identity hash code (null-safe)
System.out.println(ObjectUtils.identityToString(str1)); // java.lang.String@<hashcode>
System.out.println(ObjectUtils.identityToString(str4)); // null
// Hash code (null-safe)
System.out.println(ObjectUtils.hashCode(str1)); // hash code of str1
System.out.println(ObjectUtils.hashCode(str4)); // 0 (for null)
// Multiple hash codes
System.out.println(ObjectUtils.hashCodeMulti(str1, str2, str3)); // combined hash code
// Clone (if cloneable)
try {
String cloned = ObjectUtils.clone(str1);
System.out.println("Cloned: " + cloned);
} catch (Exception e) {
System.out.println("Clone failed: " + e.getMessage());
}
}
}

Object Validation

public class ObjectValidation {
public static void main(String[] args) {
String validString = "Hello";
String nullString = null;
String emptyString = "";
String whitespaceString = " ";
// Check if object is not null
System.out.println(ObjectUtils.isNotEmpty(validString)); // true
System.out.println(ObjectUtils.isNotEmpty(nullString)); // false
System.out.println(ObjectUtils.isNotEmpty(emptyString)); // false
System.out.println(ObjectUtils.isNotEmpty(whitespaceString)); // true
// Check if object is null
System.out.println(ObjectUtils.isNull(validString)); // false
System.out.println(ObjectUtils.isNull(nullString)); // true
// Check if object is not null
System.out.println(ObjectUtils.isNotNull(validString)); // true
System.out.println(ObjectUtils.isNotNull(nullString)); // false
// Validate with custom predicate
System.out.println(ObjectUtils.allNotNull(validString, "World", "Java")); // true
System.out.println(ObjectUtils.allNotNull(validString, nullString, "Java")); // false
System.out.println(ObjectUtils.anyNotNull(validString, nullString, "Java")); // true
System.out.println(ObjectUtils.anyNotNull(nullString, null, null)); // false
}
}

Collection and Array Operations

Array Utilities

import java.util.Arrays;
public class ArrayOperations {
public static void main(String[] args) {
String[] array1 = {"Hello", "World"};
String[] array2 = {"Java", "Programming"};
String[] nullArray = null;
// Null-safe array operations
System.out.println(ObjectUtils.isEmpty(array1)); // false
System.out.println(ObjectUtils.isEmpty(nullArray)); // true
System.out.println(ObjectUtils.isEmpty(new String[0])); // true
// Array length (null-safe)
System.out.println(ObjectUtils.length(array1)); // 2
System.out.println(ObjectUtils.length(nullArray)); // 0
// Array comparison
System.out.println(ObjectUtils.equals(array1, array1)); // true
System.out.println(ObjectUtils.equals(array1, array2)); // false
System.out.println(ObjectUtils.equals(array1, nullArray)); // false
// Array concatenation
String[] combined = ObjectUtils.addAll(array1, array2);
System.out.println(Arrays.toString(combined)); // [Hello, World, Java, Programming]
// Clone array
String[] cloned = ObjectUtils.clone(array1);
System.out.println(Arrays.toString(cloned)); // [Hello, World]
System.out.println(cloned != array1); // true (different objects)
}
}

Collection Utilities

import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
public class CollectionOperations {
public static void main(String[] args) {
List<String> list1 = Arrays.asList("Hello", "World");
List<String> list2 = Arrays.asList("Java", "Programming");
List<String> nullList = null;
// Null-safe collection operations
System.out.println(ObjectUtils.isEmpty(list1)); // false
System.out.println(ObjectUtils.isEmpty(nullList)); // true
System.out.println(ObjectUtils.isEmpty(new ArrayList<>())); // true
// Collection size (null-safe)
System.out.println(ObjectUtils.size(list1)); // 2
System.out.println(ObjectUtils.size(nullList)); // 0
// Collection comparison
System.out.println(ObjectUtils.equals(list1, list1)); // true
System.out.println(ObjectUtils.equals(list1, list2)); // false
// Merge collections
List<String> merged = new ArrayList<>();
merged.addAll(list1);
merged.addAll(list2);
System.out.println(merged); // [Hello, World, Java, Programming]
}
}

Real-World Examples

Configuration Management

import java.util.HashMap;
import java.util.Map;
public class ConfigurationManager {
public static class Config {
private String databaseUrl;
private Integer port;
private Boolean debug;
private String apiKey;
public Config(String databaseUrl, Integer port, Boolean debug, String apiKey) {
this.databaseUrl = databaseUrl;
this.port = port;
this.debug = debug;
this.apiKey = apiKey;
}
@Override
public String toString() {
return String.format("Config{dbUrl='%s', port=%d, debug=%s, apiKey='%s'}",
databaseUrl, port, debug, apiKey);
}
}
public static Config createConfig(String dbUrl, Integer port, Boolean debug, String apiKey) {
// Use ObjectUtils to provide defaults for null values
String safeDbUrl = ObjectUtils.defaultIfNull(dbUrl, "jdbc:mysql://localhost:3306/mydb");
Integer safePort = ObjectUtils.defaultIfNull(port, 8080);
Boolean safeDebug = ObjectUtils.defaultIfNull(debug, false);
String safeApiKey = ObjectUtils.defaultIfNull(apiKey, "default-key");
return new Config(safeDbUrl, safePort, safeDebug, safeApiKey);
}
public static void main(String[] args) {
// Valid configuration
Config config1 = createConfig("jdbc:mysql://localhost:3306/prod", 9090, true, "prod-key");
System.out.println(config1);
// Partial configuration (uses defaults)
Config config2 = createConfig(null, null, null, null);
System.out.println(config2);
// Mixed configuration
Config config3 = createConfig("jdbc:mysql://localhost:3306/test", null, true, null);
System.out.println(config3);
}
}

Data Validation

public class DataValidator {
public static class User {
private String name;
private String email;
private Integer age;
public User(String name, String email, Integer age) {
this.name = name;
this.email = email;
this.age = age;
}
@Override
public String toString() {
return String.format("User{name='%s', email='%s', age=%d}", name, email, age);
}
}
public static boolean isValidUser(User user) {
if (ObjectUtils.isEmpty(user)) {
return false;
}
// Check if all required fields are present
return ObjectUtils.allNotNull(user.name, user.email, user.age) &&
!user.name.trim().isEmpty() &&
user.email.contains("@") &&
user.age >= 0 && user.age <= 150;
}
public static User createValidUser(String name, String email, Integer age) {
// Validate and provide defaults
String safeName = ObjectUtils.defaultIfNull(name, "Unknown");
String safeEmail = ObjectUtils.defaultIfNull(email, "unknown@example.com");
Integer safeAge = ObjectUtils.defaultIfNull(age, 18);
return new User(safeName, safeEmail, safeAge);
}
public static void main(String[] args) {
// Valid user
User validUser = new User("John Doe", "john@example.com", 25);
System.out.println("Valid user: " + isValidUser(validUser));
// Invalid user (null values)
User invalidUser = new User(null, null, null);
System.out.println("Invalid user: " + isValidUser(invalidUser));
// User with defaults
User defaultUser = createValidUser(null, null, null);
System.out.println("Default user: " + defaultUser);
}
}

API Response Handling

import java.util.HashMap;
import java.util.Map;
public class ApiResponseHandler {
public static class ApiResponse {
private Object data;
private String message;
private Integer statusCode;
public ApiResponse(Object data, String message, Integer statusCode) {
this.data = data;
this.message = message;
this.statusCode = statusCode;
}
@Override
public String toString() {
return String.format("ApiResponse{data=%s, message='%s', statusCode=%d}",
data, message, statusCode);
}
}
public static ApiResponse createResponse(Object data, String message, Integer statusCode) {
// Use ObjectUtils to handle null values gracefully
Object safeData = ObjectUtils.defaultIfNull(data, new HashMap<>());
String safeMessage = ObjectUtils.defaultIfNull(message, "Success");
Integer safeStatusCode = ObjectUtils.defaultIfNull(statusCode, 200);
return new ApiResponse(safeData, safeMessage, safeStatusCode);
}
public static boolean isSuccessfulResponse(ApiResponse response) {
if (ObjectUtils.isEmpty(response)) {
return false;
}
return ObjectUtils.isNotNull(response.statusCode) &&
response.statusCode >= 200 &&
response.statusCode < 300;
}
public static void main(String[] args) {
// Successful response
ApiResponse success = createResponse("Data", "Success", 200);
System.out.println("Success response: " + isSuccessfulResponse(success));
// Error response
ApiResponse error = createResponse(null, "Error", 500);
System.out.println("Error response: " + isSuccessfulResponse(error));
// Response with defaults
ApiResponse defaultResponse = createResponse(null, null, null);
System.out.println("Default response: " + defaultResponse);
}
}

Performance Considerations

When to Use ObjectUtils vs Standard Java Methods

public class PerformanceComparison {
public static void main(String[] args) {
// Use ObjectUtils for null-safe operations
ObjectUtils.defaultIfNull("value", "default"); // Safe
// Use ObjectUtils for multiple null checks
ObjectUtils.allNotNull("a", "b", "c"); // Convenient
// Use standard Java methods for simple operations
"Hello".equals("Hello"); // More efficient for non-null values
// Use ObjectUtils for complex object handling
ObjectUtils.firstNonNull(null, null, "default"); // Convenient
}
}

Best Practices

  1. Always use null-safe methods when dealing with user input or external data
  2. Use defaultIfNull() for providing fallback values instead of manual null checks
  3. Use firstNonNull() for multiple fallback options in order of preference
  4. Use allNotNull() and anyNotNull() for validation instead of manual checks
  5. Consider performance for frequently called methods in loops
  6. Use appropriate methods for your specific use case

Common Pitfalls

public class CommonPitfalls {
public static void main(String[] args) {
// Pitfall 1: Not using null-safe methods
String str = null;
// str.equals("test"); // Throws NullPointerException
ObjectUtils.equals(str, "test"); // Safe, returns false
// Pitfall 2: Manual null checking instead of utilities
String value = null;
String result;
if (value != null) {
result = value;
} else {
result = "default";
}
// vs
String betterResult = ObjectUtils.defaultIfNull(value, "default");
// Pitfall 3: Not handling empty collections
List<String> list = null;
// list.size(); // Throws NullPointerException
ObjectUtils.size(list); // Safe, returns 0
// Pitfall 4: Not using appropriate validation methods
String[] array = {"a", "b", null, "d"};
// Manual check for all non-null
boolean allValid = true;
for (String item : array) {
if (item == null) {
allValid = false;
break;
}
}
// vs
boolean betterCheck = ObjectUtils.allNotNull(array);
}
}

Conclusion

ObjectUtils from Apache Commons Lang provides a robust set of utilities that make object operations safer, more convenient, and more powerful. By understanding these methods and their proper usage, you can write cleaner, more maintainable code that handles edge cases gracefully.

The key benefits include:

Start incorporating ObjectUtils into your projects and see how it simplifies your object handling code!

Resources

Written by Purusothaman Ramanujam

← Back to blog