CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-apache-commons--commons-lang3

Apache Commons Lang provides essential Java utility classes for string manipulation, object operations, array handling, date/time processing, reflection utilities, and more.

Pending
Overview
Eval results
Files

builders.mddocs/

Builder Utilities

Apache Commons Lang provides powerful builder pattern utilities that simplify the creation of equals(), hashCode(), toString(), and compareTo() methods. These builders follow fluent interfaces and handle complex cases including null values, arrays, and nested objects automatically.

Core Builder Classes

ToStringBuilder - Fluent toString() Construction

Creates readable string representations of objects with extensive customization options:

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

Basic Usage

public class Person {
    private String name;
    private int age;
    private List<String> hobbies;
    
    @Override
    public String toString() {
        return new ToStringBuilder(this)
            .append("name", name)
            .append("age", age)
            .append("hobbies", hobbies)
            .toString();
    }
}

// Output: Person@1a2b3c4d[name=John Doe,age=25,hobbies=[reading, gaming]]

ToStringBuilder Methods

// Basic field appending
public ToStringBuilder append(String fieldName, Object obj)
public ToStringBuilder append(String fieldName, boolean value)
public ToStringBuilder append(String fieldName, byte value)
public ToStringBuilder append(String fieldName, char value)
public ToStringBuilder append(String fieldName, double value)
public ToStringBuilder append(String fieldName, float value)
public ToStringBuilder append(String fieldName, int value)
public ToStringBuilder append(String fieldName, long value)
public ToStringBuilder append(String fieldName, short value)

// Array appending
public ToStringBuilder append(String fieldName, Object[] array)
public ToStringBuilder append(String fieldName, boolean[] array)
public ToStringBuilder append(String fieldName, byte[] array)
// ... similar for other primitive arrays

// Advanced appending
public ToStringBuilder appendAsObjectToString(Object object)
public ToStringBuilder appendSuper(String superToString)
public ToStringBuilder appendToString(String toString)

ToStringStyle Options

// Predefined styles
ToStringStyle.DEFAULT_STYLE           // ClassName@hashcode[field=value,field=value]
ToStringStyle.MULTI_LINE_STYLE        // Each field on separate line
ToStringStyle.NO_FIELD_NAMES_STYLE    // Values without field names
ToStringStyle.SHORT_PREFIX_STYLE      // ClassName[field=value,field=value]
ToStringStyle.SIMPLE_STYLE            // field=value,field=value
ToStringStyle.NO_CLASS_NAME_STYLE     // [field=value,field=value]
ToStringStyle.JSON_STYLE              // {"field":"value","field":"value"}

Usage Examples:

public class Employee {
    private String name = "John Doe";
    private int id = 12345;
    private String[] skills = {"Java", "Python", "SQL"};
    private Address address = new Address("123 Main St", "New York");
    
    // Default style
    public String toString() {
        return new ToStringBuilder(this)
            .append("name", name)
            .append("id", id)
            .append("skills", skills)
            .append("address", address)
            .toString();
    }
    // Output: Employee@1a2b3c4d[name=John Doe,id=12345,skills={Java,Python,SQL},address=Address@5f6g7h8i[...]]
    
    // JSON style
    public String toJsonString() {
        return new ToStringBuilder(this, ToStringStyle.JSON_STYLE)
            .append("name", name)
            .append("id", id)
            .append("skills", skills)
            .toString();
    }
    // Output: {"name":"John Doe","id":12345,"skills":["Java","Python","SQL"]}
    
    // Multi-line style
    public String toMultiLineString() {
        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
            .append("name", name)
            .append("id", id)
            .append("skills", skills)
            .toString();
    }
    // Output:
    // Employee@1a2b3c4d[
    //   name=John Doe
    //   id=12345
    //   skills={Java,Python,SQL}
    // ]
    
    // No field names style  
    public String toSimpleString() {
        return new ToStringBuilder(this, ToStringStyle.NO_FIELD_NAMES_STYLE)
            .append(name)
            .append(id)
            .append(skills)
            .toString();
    }
    // Output: Employee@1a2b3c4d[John Doe,12345,{Java,Python,SQL}]
}

ReflectionToStringBuilder - Automatic toString()

Automatically generates toString() using reflection:

import org.apache.commons.lang3.builder.ReflectionToStringBuilder;

public class Product {
    private String name = "Laptop";
    private double price = 999.99;
    private boolean inStock = true;
    
    @Override
    public String toString() {
        return ReflectionToStringBuilder.toString(this);
    }
    // Automatically includes all fields
    
    // With custom style
    public String toJsonString() {
        return ReflectionToStringBuilder.toString(this, ToStringStyle.JSON_STYLE);
    }
    
    // Exclude specific fields
    public String toStringExcludePrice() {
        return ReflectionToStringBuilder.toStringExclude(this, "price");
    }
    
    // Include only specific fields
    public String toStringOnlyName() {
        return ReflectionToStringBuilder.toStringInclude(this, "name");
    }
}

EqualsBuilder - Fluent equals() Construction

Creates robust equals() methods with null safety and type checking:

import org.apache.commons.lang3.builder.EqualsBuilder;

Basic EqualsBuilder Usage

public class Person {
    private String firstName;
    private String lastName;
    private int age;
    private Date birthDate;
    private String[] hobbies;
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        
        Person person = (Person) obj;
        
        return new EqualsBuilder()
            .append(firstName, person.firstName)
            .append(lastName, person.lastName)
            .append(age, person.age)
            .append(birthDate, person.birthDate)
            .append(hobbies, person.hobbies)
            .isEquals();
    }
}

EqualsBuilder Methods

// Basic field comparison
public EqualsBuilder append(Object lhs, Object rhs)
public EqualsBuilder append(boolean lhs, boolean rhs)
public EqualsBuilder append(byte lhs, byte rhs)
public EqualsBuilder append(char lhs, char rhs)
public EqualsBuilder append(double lhs, double rhs)
public EqualsBuilder append(float lhs, float rhs)
public EqualsBuilder append(int lhs, int rhs)
public EqualsBuilder append(long lhs, long rhs)
public EqualsBuilder append(short lhs, short rhs)

// Array comparison
public EqualsBuilder append(Object[] lhs, Object[] rhs)
public EqualsBuilder append(boolean[] lhs, boolean[] rhs)
// ... similar for other primitive arrays

// Advanced comparison
public EqualsBuilder appendSuper(boolean superEquals)
public boolean isEquals()

Reflection-Based equals()

public class Employee {
    private String id;
    private String name;
    private String department;
    private double salary;
    
    @Override
    public boolean equals(Object obj) {
        return EqualsBuilder.reflectionEquals(this, obj);
    }
    
    // Exclude specific fields from comparison
    public boolean equalsIgnoreSalary(Object obj) {
        return EqualsBuilder.reflectionEquals(this, obj, "salary");
    }
    
    // Include only up to a certain class in hierarchy
    public boolean equalsShallow(Object obj) {
        return EqualsBuilder.reflectionEquals(this, obj, false, Employee.class);
    }
}

HashCodeBuilder - Fluent hashCode() Construction

Creates consistent hashCode() methods that work correctly with equals():

import org.apache.commons.lang3.builder.HashCodeBuilder;

Basic HashCodeBuilder Usage

public class Person {
    private String firstName;
    private String lastName;
    private int age;
    private Date birthDate;
    
    @Override
    public int hashCode() {
        return new HashCodeBuilder(17, 37)  // Two different odd prime numbers
            .append(firstName)
            .append(lastName)
            .append(age)
            .append(birthDate)
            .toHashCode();
    }
}

HashCodeBuilder Methods

// Basic field hashing
public HashCodeBuilder append(Object object)
public HashCodeBuilder append(boolean value)
public HashCodeBuilder append(byte value)
public HashCodeBuilder append(char value)
public HashCodeBuilder append(double value)
public HashCodeBuilder append(float value)
public HashCodeBuilder append(int value)
public HashCodeBuilder append(long value)
public HashCodeBuilder append(short value)

// Array hashing
public HashCodeBuilder append(Object[] array)
public HashCodeBuilder append(boolean[] array)
// ... similar for other primitive arrays

// Advanced hashing
public HashCodeBuilder appendSuper(int superHashCode)
public int toHashCode()

Reflection-Based hashCode()

public class Product {
    private String sku;
    private String name;
    private double price;
    private String category;
    
    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }
    
    // Exclude specific fields
    public int hashCodeIgnorePrice() {
        return HashCodeBuilder.reflectionHashCode(this, "price");
    }
    
    // Custom initial values and multiplier
    public int customHashCode() {
        return HashCodeBuilder.reflectionHashCode(17, 37, this);
    }
}

CompareToBuilder - Fluent compareTo() Construction

Creates Comparable implementations with proper null handling:

import org.apache.commons.lang3.builder.CompareToBuilder;

Basic CompareToBuilder Usage

public class Person implements Comparable<Person> {
    private String lastName;
    private String firstName;
    private int age;
    private Date birthDate;
    
    @Override
    public int compareTo(Person other) {
        return new CompareToBuilder()
            .append(lastName, other.lastName)
            .append(firstName, other.firstName)
            .append(age, other.age)
            .append(birthDate, other.birthDate)
            .toComparison();
    }
}

CompareToBuilder Methods

// Basic field comparison
public CompareToBuilder append(Object lhs, Object rhs)
public CompareToBuilder append(Object lhs, Object rhs, Comparator<?> comparator)
public CompareToBuilder append(boolean lhs, boolean rhs)
public CompareToBuilder append(byte lhs, byte rhs)
public CompareToBuilder append(char lhs, char rhs)
public CompareToBuilder append(double lhs, double rhs)
public CompareToBuilder append(float lhs, float rhs)
public CompareToBuilder append(int lhs, int rhs)
public CompareToBuilder append(long lhs, long rhs)
public CompareToBuilder append(short lhs, short rhs)

// Array comparison
public CompareToBuilder append(Object[] lhs, Object[] rhs)
public CompareToBuilder append(Object[] lhs, Object[] rhs, Comparator<?> comparator)
// ... similar for other arrays

// Advanced comparison
public CompareToBuilder appendSuper(int superCompareTo)
public int toComparison()

Reflection-Based compareTo()

public class Employee implements Comparable<Employee> {
    private String department;
    private String name;
    private int level;
    private double salary;
    
    @Override
    public int compareTo(Employee other) {
        return CompareToBuilder.reflectionCompare(this, other);
    }
    
    // Exclude specific fields from comparison
    public int compareIgnoreSalary(Employee other) {
        return CompareToBuilder.reflectionCompare(this, other, "salary");
    }
    
    // Custom field order
    public int compareCustomOrder(Employee other) {
        return new CompareToBuilder()
            .append(department, other.department)    // Primary sort
            .append(level, other.level)              // Secondary sort
            .append(name, other.name)                // Tertiary sort
            .toComparison();
    }
}

Advanced Builder Patterns

Custom ToStringStyle

public class CustomToStringStyle extends ToStringStyle {
    
    public CustomToStringStyle() {
        super();
        this.setUseShortClassName(true);
        this.setUseIdentityHashCode(false);
        this.setFieldSeparator(" | ");
        this.setFieldNameValueSeparator(": ");
        this.setContentStart("[");
        this.setContentEnd("]");
        this.setNullText("NULL");
        this.setArrayStart("{");
        this.setArrayEnd("}");
        this.setArraySeparator(", ");
    }
}

// Usage
public String customToString() {
    return new ToStringBuilder(this, new CustomToStringStyle())
        .append("field1", value1)
        .append("field2", value2)
        .toString();
}
// Output: ClassName[field1: value1 | field2: value2]

Builder Annotations

import org.apache.commons.lang3.builder.ToStringExclude;
import org.apache.commons.lang3.builder.EqualsExclude;
import org.apache.commons.lang3.builder.HashCodeExclude;

public class User {
    private String username;
    private String email;
    
    @ToStringExclude
    @EqualsExclude
    @HashCodeExclude
    private String password;  // Excluded from toString, equals, and hashCode
    
    private Date lastLogin;
    
    @Override
    public String toString() {
        return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
        // password field will be automatically excluded
    }
    
    @Override
    public boolean equals(Object obj) {
        return EqualsBuilder.reflectionEquals(this, obj);
        // password field will be automatically excluded
    }
    
    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
        // password field will be automatically excluded
    }
}

Complete Entity Example

public class Order implements Comparable<Order> {
    private Long id;
    private String orderNumber;
    private Date orderDate;
    private BigDecimal totalAmount;
    private OrderStatus status;
    private Customer customer;
    private List<OrderItem> items;
    
    // Constructor, getters, setters...
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        
        Order order = (Order) obj;
        
        return new EqualsBuilder()
            .append(id, order.id)
            .append(orderNumber, order.orderNumber)
            .isEquals();
    }
    
    @Override
    public int hashCode() {
        return new HashCodeBuilder(17, 37)
            .append(id)
            .append(orderNumber)
            .toHashCode();
    }
    
    @Override
    public String toString() {
        return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
            .append("id", id)
            .append("orderNumber", orderNumber)
            .append("orderDate", orderDate)
            .append("totalAmount", totalAmount)
            .append("status", status)
            .append("customerName", customer != null ? customer.getName() : null)
            .append("itemCount", items != null ? items.size() : 0)
            .toString();
    }
    
    @Override
    public int compareTo(Order other) {
        return new CompareToBuilder()
            .append(orderDate, other.orderDate)      // Primary: newest first
            .append(id, other.id)                    // Secondary: by ID
            .toComparison();
    }
    
    // Debug toString with all details
    public String toDetailedString() {
        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
            .append("id", id)
            .append("orderNumber", orderNumber)
            .append("orderDate", orderDate)
            .append("totalAmount", totalAmount)
            .append("status", status)
            .append("customer", customer)
            .append("items", items)
            .toString();
    }
}

Builder Utilities Integration

Factory Methods for Builders

public final class BuilderUtils {
    
    // Fluent builder creation
    public static ToStringBuilder toStringBuilder(Object object) {
        return new ToStringBuilder(object, ToStringStyle.SHORT_PREFIX_STYLE);
    }
    
    public static ToStringBuilder jsonBuilder(Object object) {
        return new ToStringBuilder(object, ToStringStyle.JSON_STYLE);
    }
    
    public static EqualsBuilder equalsBuilder() {
        return new EqualsBuilder();
    }
    
    public static HashCodeBuilder hashCodeBuilder() {
        return new HashCodeBuilder(17, 37);
    }
    
    public static CompareToBuilder compareToBuilder() {
        return new CompareToBuilder();
    }
    
    // Null-safe reflection methods
    public static String safeToString(Object obj) {
        return obj != null ? ReflectionToStringBuilder.toString(obj) : "null";
    }
    
    public static boolean safeEquals(Object obj1, Object obj2) {
        if (obj1 == obj2) return true;
        if (obj1 == null || obj2 == null) return false;
        if (obj1.getClass() != obj2.getClass()) return false;
        
        return EqualsBuilder.reflectionEquals(obj1, obj2);
    }
    
    public static int safeHashCode(Object obj) {
        return obj != null ? HashCodeBuilder.reflectionHashCode(obj) : 0;
    }
}

Validation with Builders

@Component
public class EntityValidator {
    
    public <T> void validateEqualsHashCode(T obj1, T obj2) {
        boolean equals = obj1.equals(obj2);
        boolean hashCodesEqual = obj1.hashCode() == obj2.hashCode();
        
        if (equals && !hashCodesEqual) {
            throw new IllegalStateException(
                "Objects are equal but have different hash codes: " +
                "obj1.hashCode()=" + obj1.hashCode() + 
                ", obj2.hashCode()=" + obj2.hashCode());
        }
        
        // Log for debugging
        log.debug("Validation passed for objects: {}, {}", 
            safeToString(obj1), safeToString(obj2));
    }
    
    public <T extends Comparable<T>> void validateComparable(T obj1, T obj2) {
        int comparison = obj1.compareTo(obj2);
        boolean equals = obj1.equals(obj2);
        
        if (comparison == 0 && !equals) {
            throw new IllegalStateException(
                "Objects compare as equal but are not equal: " +
                safeToString(obj1) + " vs " + safeToString(obj2));
        }
        
        if (comparison != 0 && equals) {
            throw new IllegalStateException(
                "Objects are equal but don't compare as equal: " +
                safeToString(obj1) + " vs " + safeToString(obj2));
        }
    }
}

Performance Considerations

public class OptimizedEntity {
    private final String id;
    private final String name;
    private final int value;
    
    // Cache hash code for immutable objects
    private transient int hashCode = 0;
    
    public OptimizedEntity(String id, String name, int value) {
        this.id = id;
        this.name = name;
        this.value = value;
    }
    
    @Override
    public boolean equals(Object obj) {
        // Fast path for same reference
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        
        OptimizedEntity other = (OptimizedEntity) obj;
        
        // Most discriminating field first
        return new EqualsBuilder()
            .append(id, other.id)        // Usually unique
            .append(value, other.value)  // Numeric comparison is fast
            .append(name, other.name)    // String comparison last
            .isEquals();
    }
    
    @Override
    public int hashCode() {
        // Cache hash code for immutable objects
        if (hashCode == 0) {
            hashCode = new HashCodeBuilder(17, 37)
                .append(id)
                .append(name)
                .append(value)
                .toHashCode();
        }
        return hashCode;
    }
    
    @Override
    public String toString() {
        // Use simple concatenation for performance-critical paths
        return getClass().getSimpleName() + "[id=" + id + ",name=" + name + ",value=" + value + "]";
    }
}

The builder utilities in Apache Commons Lang provide a robust foundation for implementing the essential Object methods with proper null safety, array handling, and customizable formatting, reducing boilerplate code while ensuring correctness and consistency.

Install with Tessl CLI

npx tessl i tessl/maven-org-apache-commons--commons-lang3

docs

array-utilities.md

builders.md

concurrent-utilities.md

date-time-utilities.md

exception-utilities.md

index.md

math-utilities.md

object-utilities.md

string-utilities.md

validation-utilities.md

tile.json