Apache Commons Lang provides essential Java utility classes for string manipulation, object operations, array handling, date/time processing, reflection utilities, and more.
—
Apache Commons Lang provides robust mathematical utilities through NumberUtils, Range classes, and Fraction operations. These utilities offer safe number parsing, validation, comparison, and range operations that handle edge cases and null values gracefully.
Provides 82 static methods for safe number operations, parsing, and validation:
import org.apache.commons.lang3.math.NumberUtils;// Wrapper type constants for common values
public static final Long LONG_ZERO = Long.valueOf(0L)
public static final Long LONG_ONE = Long.valueOf(1L)
public static final Long LONG_MINUS_ONE = Long.valueOf(-1L)
public static final Integer INTEGER_ZERO = Integer.valueOf(0)
public static final Integer INTEGER_ONE = Integer.valueOf(1)
public static final Integer INTEGER_TWO = Integer.valueOf(2)
public static final Integer INTEGER_MINUS_ONE = Integer.valueOf(-1)
public static final Short SHORT_ZERO = Short.valueOf((short) 0)
public static final Short SHORT_ONE = Short.valueOf((short) 1)
public static final Short SHORT_MINUS_ONE = Short.valueOf((short) -1)
public static final Byte BYTE_ZERO = Byte.valueOf((byte) 0)
public static final Byte BYTE_ONE = Byte.valueOf((byte) 1)
public static final Byte BYTE_MINUS_ONE = Byte.valueOf((byte) -1)
public static final Double DOUBLE_ZERO = Double.valueOf(0.0d)
public static final Double DOUBLE_ONE = Double.valueOf(1.0d)
public static final Double DOUBLE_MINUS_ONE = Double.valueOf(-1.0d)
public static final Float FLOAT_ZERO = Float.valueOf(0.0f)
public static final Float FLOAT_ONE = Float.valueOf(1.0f)
public static final Float FLOAT_MINUS_ONE = Float.valueOf(-1.0f)Usage Examples:
// Using predefined constants to avoid object creation
Integer zero = NumberUtils.INTEGER_ZERO; // Better than Integer.valueOf(0)
Long one = NumberUtils.LONG_ONE; // Better than Long.valueOf(1L)
Double minusOne = NumberUtils.DOUBLE_MINUS_ONE; // Better than Double.valueOf(-1.0d)// Integer parsing with defaults
public static int toInt(String str)
public static int toInt(String str, int defaultValue)
// Long parsing with defaults
public static long toLong(String str)
public static long toLong(String str, long defaultValue)
// Float parsing with defaults
public static float toFloat(String str)
public static float toFloat(String str, float defaultValue)
// Double parsing with defaults
public static double toDouble(String str)
public static double toDouble(String str, double defaultValue)
// Byte parsing with defaults
public static byte toByte(String str)
public static byte toByte(String str, byte defaultValue)
// Short parsing with defaults
public static short toShort(String str)
public static short toShort(String str, short defaultValue)Usage Examples:
// Safe parsing without exceptions
int number1 = NumberUtils.toInt("123"); // 123
int number2 = NumberUtils.toInt("invalid"); // 0 (default)
int number3 = NumberUtils.toInt("invalid", -1); // -1 (custom default)
int number4 = NumberUtils.toInt(null, 100); // 100
// Parsing different number types
long longValue = NumberUtils.toLong("999999999999"); // 999999999999L
double doubleValue = NumberUtils.toDouble("3.14"); // 3.14
float floatValue = NumberUtils.toFloat("2.5f"); // 2.5f
byte byteValue = NumberUtils.toByte("127"); // 127
short shortValue = NumberUtils.toShort("1000"); // 1000
// Handling edge cases
double nan = NumberUtils.toDouble("NaN"); // NaN
double infinity = NumberUtils.toDouble("Infinity"); // Infinity// Create Number objects from strings
public static Number createNumber(String str) throws NumberFormatException
public static BigInteger createBigInteger(String str)
public static BigDecimal createBigDecimal(String str)
// Parse with specific radix
public static int toInt(String str, int defaultValue, int radix)
public static long toLong(String str, long defaultValue, int radix)Usage Examples:
// Automatic number type detection
Number num1 = NumberUtils.createNumber("123"); // Integer
Number num2 = NumberUtils.createNumber("123L"); // Long
Number num3 = NumberUtils.createNumber("123.45"); // Double
Number num4 = NumberUtils.createNumber("123.45f"); // Float
Number num5 = NumberUtils.createNumber("123.45d"); // Double
// Big number creation
BigInteger bigInt = NumberUtils.createBigInteger("12345678901234567890");
BigDecimal bigDec = NumberUtils.createBigDecimal("123.456789012345678901234");
// Parsing with different radix
int hex = NumberUtils.toInt("FF", 0, 16); // 255
int binary = NumberUtils.toInt("1010", 0, 2); // 10
int octal = NumberUtils.toInt("17", 0, 8); // 15// Check if string represents a number
public static boolean isCreatable(String str)
public static boolean isParsable(String str)
// Specific type validation
public static boolean isDigits(String str)Usage Examples:
// Number format validation
boolean isNum1 = NumberUtils.isCreatable("123"); // true
boolean isNum2 = NumberUtils.isCreatable("123.45"); // true
boolean isNum3 = NumberUtils.isCreatable("123L"); // true
boolean isNum4 = NumberUtils.isCreatable("invalid"); // false
boolean isNum5 = NumberUtils.isCreatable(null); // false
// Parsable validation (stricter)
boolean parsable1 = NumberUtils.isParsable("123"); // true
boolean parsable2 = NumberUtils.isParsable("123L"); // false (L suffix not parsable)
boolean parsable3 = NumberUtils.isParsable("123.0"); // true
// Digits only validation
boolean digits1 = NumberUtils.isDigits("123"); // true
boolean digits2 = NumberUtils.isDigits("123.45"); // false (contains decimal)
boolean digits3 = NumberUtils.isDigits("-123"); // false (contains minus sign)// Min operations for all numeric types
public static byte min(byte... array)
public static double min(double... array)
public static float min(float... array)
public static int min(int... array)
public static long min(long... array)
public static short min(short... array)
// Max operations for all numeric types
public static byte max(byte... array)
public static double max(double... array)
public static float max(float... array)
public static int max(int... array)
public static long max(long... array)
public static short max(short... array)Usage Examples:
// Finding minimum values
int minInt = NumberUtils.min(5, 2, 8, 1, 9); // 1
double minDouble = NumberUtils.min(3.14, 2.71, 1.41); // 1.41
long minLong = NumberUtils.min(100L, 200L, 50L); // 50L
// Finding maximum values
int maxInt = NumberUtils.max(5, 2, 8, 1, 9); // 9
float maxFloat = NumberUtils.max(1.1f, 2.2f, 3.3f); // 3.3f
// Handling single element arrays
int single = NumberUtils.min(42); // 42
int singleMax = NumberUtils.max(42); // 42Apache Commons Lang provides several Range implementations for different numeric types:
import org.apache.commons.lang3.Range;// Range creation methods
public static <T extends Comparable<? super T>> Range<T> between(T fromInclusive, T toInclusive)
public static <T> Range<T> between(T fromInclusive, T toInclusive, Comparator<T> comparator)
public static <T extends Comparable<? super T>> Range<T> is(T element)
public static <T> Range<T> is(T element, Comparator<T> comparator)
// Range operations
public boolean contains(T element)
public boolean containsRange(Range<T> otherRange)
public boolean isOverlappedBy(Range<T> otherRange)
public T getMinimum()
public T getMaximum()
public Comparator<T> getComparator()Usage Examples:
// Creating ranges
Range<Integer> ageRange = Range.between(18, 65); // 18 to 65 inclusive
Range<String> nameRange = Range.between("A", "M"); // Alphabetical range A-M
Range<Integer> exact = Range.is(42); // Exact value range
// Range validation
boolean inRange = ageRange.contains(25); // true
boolean tooYoung = ageRange.contains(16); // false
boolean validName = nameRange.contains("John"); // true
// Range relationships
Range<Integer> overlap = Range.between(60, 70);
boolean overlaps = ageRange.isOverlappedBy(overlap); // true
boolean contains = ageRange.containsRange(Range.between(20, 30)); // true
// Range boundaries
Integer min = ageRange.getMinimum(); // 18
Integer max = ageRange.getMaximum(); // 65import org.apache.commons.lang3.IntegerRange;// Integer range creation
public static IntegerRange of(int fromInclusive, int toInclusive)
public static IntegerRange of(Integer fromInclusive, Integer toInclusive)Usage Examples:
// Integer ranges
IntegerRange scoreRange = IntegerRange.of(0, 100);
IntegerRange passingRange = IntegerRange.of(60, 100);
// Validation
boolean validScore = scoreRange.contains(85); // true
boolean passing = passingRange.contains(85); // true
boolean failing = passingRange.contains(45); // false
// Range operations
int minScore = scoreRange.getMinimum(); // 0
int maxScore = scoreRange.getMaximum(); // 100import org.apache.commons.lang3.LongRange;
import org.apache.commons.lang3.DoubleRange;// Long range operations
LongRange timestampRange = LongRange.of(1000000L, 9999999L);
boolean validTimestamp = timestampRange.contains(5000000L); // true
// Double range operations
DoubleRange temperatureRange = DoubleRange.of(-40.0, 50.0);
boolean validTemp = temperatureRange.contains(23.5); // true
boolean tooHot = temperatureRange.contains(75.0); // falseProvides exact fraction arithmetic without floating-point precision issues:
import org.apache.commons.lang3.math.Fraction;// Predefined fraction constants
public static final Fraction ZERO = new Fraction(0, 1)
public static final Fraction ONE = new Fraction(1, 1)
public static final Fraction ONE_HALF = new Fraction(1, 2)
public static final Fraction ONE_THIRD = new Fraction(1, 3)
public static final Fraction TWO_THIRDS = new Fraction(2, 3)
public static final Fraction ONE_QUARTER = new Fraction(1, 4)
public static final Fraction TWO_QUARTERS = new Fraction(2, 4)
public static final Fraction THREE_QUARTERS = new Fraction(3, 4)
public static final Fraction ONE_FIFTH = new Fraction(1, 5)
public static final Fraction TWO_FIFTHS = new Fraction(2, 5)
public static final Fraction THREE_FIFTHS = new Fraction(3, 5)
public static final Fraction FOUR_FIFTHS = new Fraction(4, 5)// Fraction creation
public static Fraction getFraction(int numerator, int denominator)
public static Fraction getFraction(int whole, int numerator, int denominator)
public static Fraction getFraction(double value)
public static Fraction getFraction(String str)
// Arithmetic operations
public Fraction add(Fraction fraction)
public Fraction subtract(Fraction fraction)
public Fraction multiply(Fraction fraction)
public Fraction divide(Fraction fraction)
public Fraction pow(int power)
public Fraction abs()
public Fraction negate()Usage Examples:
// Creating fractions
Fraction half = Fraction.ONE_HALF; // 1/2
Fraction third = Fraction.getFraction(1, 3); // 1/3
Fraction mixed = Fraction.getFraction(2, 1, 4); // 2 1/4 = 9/4
Fraction fromDouble = Fraction.getFraction(0.75); // 3/4
Fraction fromString = Fraction.getFraction("2/3"); // 2/3
// Arithmetic operations
Fraction sum = half.add(third); // 1/2 + 1/3 = 5/6
Fraction difference = third.subtract(Fraction.ONE_QUARTER); // 1/3 - 1/4 = 1/12
Fraction product = half.multiply(third); // 1/2 * 1/3 = 1/6
Fraction quotient = half.divide(third); // 1/2 ÷ 1/3 = 3/2
// Powers and signs
Fraction squared = half.pow(2); // (1/2)² = 1/4
Fraction absolute = Fraction.getFraction(-3, 4).abs(); // 3/4
Fraction negated = half.negate(); // -1/2// Conversion methods
public int getNumerator()
public int getDenominator()
public double doubleValue()
public float floatValue()
public int intValue()
public long longValue()
// Comparison methods
public int compareTo(Fraction other)
public boolean equals(Object obj)Usage Examples:
// Accessing fraction parts
Fraction frac = Fraction.getFraction(3, 4);
int numerator = frac.getNumerator(); // 3
int denominator = frac.getDenominator(); // 4
// Converting to primitive types
double decimal = frac.doubleValue(); // 0.75
float floatVal = frac.floatValue(); // 0.75f
int rounded = frac.intValue(); // 0 (truncated)
// Comparison
Fraction a = Fraction.ONE_HALF;
Fraction b = Fraction.ONE_THIRD;
int comparison = a.compareTo(b); // 1 (1/2 > 1/3)
boolean equal = a.equals(Fraction.getFraction(2, 4)); // true (equivalent fractions)Provides IEEE 754-compliant min/max operations that handle NaN correctly:
import org.apache.commons.lang3.math.IEEE754rUtils;// IEEE 754 compliant min/max operations
public static double min(double... array)
public static float min(float... array)
public static double max(double... array)
public static float max(float... array)Usage Examples:
// Proper handling of NaN values
double min1 = IEEE754rUtils.min(1.0, Double.NaN, 3.0); // 1.0 (ignores NaN)
double max1 = IEEE754rUtils.max(1.0, Double.NaN, 3.0); // 3.0 (ignores NaN)
// Compare with regular Math.min/max
double regularMin = Math.min(1.0, Double.NaN); // NaN (incorrect)
double ieee754Min = IEEE754rUtils.min(1.0, Double.NaN); // 1.0 (correct)public class CustomRanges {
// Percentage range validation
public static class PercentageRange {
private static final DoubleRange PERCENTAGE = DoubleRange.of(0.0, 100.0);
public static boolean isValidPercentage(double value) {
return PERCENTAGE.contains(value);
}
public static void validatePercentage(double value) {
Validate.isTrue(isValidPercentage(value),
"Percentage must be between 0 and 100, got: %f", value);
}
}
// Port number range validation
public static class PortRange {
private static final IntegerRange VALID_PORTS = IntegerRange.of(1, 65535);
private static final IntegerRange WELL_KNOWN_PORTS = IntegerRange.of(1, 1023);
public static boolean isValidPort(int port) {
return VALID_PORTS.contains(port);
}
public static boolean isWellKnownPort(int port) {
return WELL_KNOWN_PORTS.contains(port);
}
}
// Date range operations
public static class DateRange {
public static Range<LocalDate> between(LocalDate start, LocalDate end) {
return Range.between(start, end);
}
public static boolean isWeekend(LocalDate date) {
DayOfWeek dayOfWeek = date.getDayOfWeek();
return dayOfWeek == DayOfWeek.SATURDAY || dayOfWeek == DayOfWeek.SUNDAY;
}
public static boolean isInCurrentMonth(LocalDate date) {
LocalDate now = LocalDate.now();
Range<LocalDate> currentMonth = Range.between(
now.withDayOfMonth(1),
now.withDayOfMonth(now.lengthOfMonth())
);
return currentMonth.contains(date);
}
}
}public class NumberFormatUtils {
// Safe number parsing with multiple formats
public static OptionalInt parseIntSafely(String value) {
if (StringUtils.isBlank(value)) {
return OptionalInt.empty();
}
// Try different formats
String cleaned = StringUtils.strip(value);
// Remove common formatting
cleaned = StringUtils.remove(cleaned, ',');
cleaned = StringUtils.remove(cleaned, ' ');
if (NumberUtils.isCreatable(cleaned)) {
try {
return OptionalInt.of(NumberUtils.createNumber(cleaned).intValue());
} catch (NumberFormatException e) {
return OptionalInt.empty();
}
}
return OptionalInt.empty();
}
// Parse with validation
public static int parseIntInRange(String value, IntegerRange range, int defaultValue) {
OptionalInt parsed = parseIntSafely(value);
if (parsed.isPresent() && range.contains(parsed.getAsInt())) {
return parsed.getAsInt();
}
return defaultValue;
}
// Currency amount parsing
public static BigDecimal parseCurrency(String amount) {
if (StringUtils.isBlank(amount)) {
return BigDecimal.ZERO;
}
// Remove currency symbols and whitespace
String cleaned = amount.replaceAll("[^0-9.-]", "");
try {
return NumberUtils.createBigDecimal(cleaned);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid currency amount: " + amount, e);
}
}
}public class EfficientMathOperations {
// Cache commonly used ranges
private static final Map<String, IntegerRange> RANGE_CACHE = Map.of(
"age", IntegerRange.of(0, 150),
"percentage", IntegerRange.of(0, 100),
"score", IntegerRange.of(0, 100),
"priority", IntegerRange.of(1, 10)
);
// Reuse range instances
public static boolean isValidAge(int age) {
return RANGE_CACHE.get("age").contains(age);
}
// Bulk validation
public static List<Integer> filterValidNumbers(String[] inputs, IntegerRange validRange) {
return Arrays.stream(inputs)
.filter(StringUtils::isNotBlank)
.filter(NumberUtils::isCreatable)
.mapToInt(NumberUtils::toInt)
.filter(validRange::contains)
.boxed()
.collect(Collectors.toList());
}
// Avoid repeated parsing
public static class NumberCache {
private final Map<String, Number> cache = new ConcurrentHashMap<>();
public Number getOrParse(String value) {
return cache.computeIfAbsent(value, v -> {
if (NumberUtils.isCreatable(v)) {
return NumberUtils.createNumber(v);
}
return NumberUtils.INTEGER_ZERO;
});
}
}
}@Component
public class NumericValidator {
public void validateScore(Integer score) {
Validate.notNull(score, "Score cannot be null");
IntegerRange validScore = IntegerRange.of(0, 100);
Validate.isTrue(validScore.contains(score),
"Score must be between 0 and 100, got: %d", score);
}
public void validateTemperature(String tempStr) {
Validate.notBlank(tempStr, "Temperature cannot be blank");
double temp = NumberUtils.toDouble(tempStr, Double.NaN);
Validate.isTrue(!Double.isNaN(temp), "Invalid temperature format: %s", tempStr);
DoubleRange validRange = DoubleRange.of(-273.15, 1000.0); // Celsius
Validate.isTrue(validRange.contains(temp),
"Temperature out of valid range: %f", temp);
}
public Fraction validateFraction(String fractionStr) {
Validate.notBlank(fractionStr, "Fraction cannot be blank");
try {
Fraction fraction = Fraction.getFraction(fractionStr);
Validate.notNull(fraction, "Invalid fraction format: %s", fractionStr);
return fraction;
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid fraction: " + fractionStr, e);
}
}
}@Configuration
public class MathConfiguration {
@Value("${app.min-age:18}")
private String minAgeStr;
@Value("${app.max-age:65}")
private String maxAgeStr;
@Bean
public IntegerRange ageRange() {
int minAge = NumberUtils.toInt(minAgeStr, 18);
int maxAge = NumberUtils.toInt(maxAgeStr, 65);
Validate.isTrue(minAge < maxAge, "Min age must be less than max age");
return IntegerRange.of(minAge, maxAge);
}
@Bean
public DoubleRange temperatureRange(@Value("${app.min-temp:-40}") String minTemp,
@Value("${app.max-temp:50}") String maxTemp) {
double min = NumberUtils.toDouble(minTemp, -40.0);
double max = NumberUtils.toDouble(maxTemp, 50.0);
return DoubleRange.of(min, max);
}
}The math utilities in Apache Commons Lang provide robust, null-safe mathematical operations with proper handling of edge cases, making numerical computations more reliable and maintainable in Java applications.
Install with Tessl CLI
npx tessl i tessl/maven-org-apache-commons--commons-lang3