How to check if a String is numeric in Java
Categories:
How to Check if a String is Numeric in Java

Learn various robust methods to determine if a given Java String contains only numeric characters, handling different edge cases and performance considerations.
Determining whether a Java String
represents a numeric value is a common task in programming. This seemingly simple requirement can become complex when considering various definitions of "numeric" â integers, decimals, positive/negative numbers, and even scientific notation. This article explores several reliable methods, from basic character checks to leveraging built-in library functions, helping you choose the best approach for your specific needs.
Understanding the 'Numeric' Definition
Before diving into implementation, it's crucial to define what constitutes a 'numeric' string for your application. Do you need to check for:
- Integers only? (e.g., "123", "-45")
- Decimal numbers? (e.g., "3.14", "-0.5")
- Positive numbers only?
- Numbers with leading/trailing spaces? (e.g., " 123 ")
- Scientific notation? (e.g., "1.23e-5")
Each definition might lead to a different implementation strategy. Most common scenarios involve checking for valid integers or floating-point numbers.
flowchart TD A[Start] --> B{Input String?} B -- No --> E[Invalid] B -- Yes --> C{Definition of 'Numeric'?} C -- Integer --> D1[Try Integer.parseInt()] C -- Decimal --> D2[Try Double.parseDouble()] C -- Custom --> D3[Regex or Character.isDigit()] D1 --> F{Exception?} D2 --> F{Exception?} D3 --> F{Match?} F -- Yes --> E[Invalid] F -- No --> G[Valid Numeric] G --> H[End] E --> H[End]
Decision flow for checking if a String is numeric
Method 1: Using Integer.parseInt()
or Double.parseDouble()
The most straightforward way to check if a string represents a number is to attempt to parse it into the desired numeric type. If the string is not a valid number, these methods will throw a NumberFormatException
. This approach is robust for standard integer and floating-point formats.
public class NumericCheck {
public static boolean isInteger(String str) {
if (str == null || str.isEmpty()) {
return false;
}
try {
Integer.parseInt(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
public static boolean isDouble(String str) {
if (str == null || str.isEmpty()) {
return false;
}
try {
Double.parseDouble(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
public static void main(String[] args) {
System.out.println("Is '123' an integer? " + isInteger("123")); // true
System.out.println("Is '-45' an integer? " + isInteger("-45")); // true
System.out.println("Is '123.45' an integer? " + isInteger("123.45")); // false
System.out.println("Is 'abc' an integer? " + isInteger("abc")); // false
System.out.println("Is '' an integer? " + isInteger("")); // false
System.out.println("Is null an integer? " + isInteger(null)); // false
System.out.println("\nIs '3.14' a double? " + isDouble("3.14")); // true
System.out.println("Is '-0.5' a double? " + isDouble("-0.5")); // true
System.out.println("Is '100' a double? " + isDouble("100")); // true
System.out.println("Is '1.23e-5' a double? " + isDouble("1.23e-5")); // true
System.out.println("Is 'hello' a double? " + isDouble("hello")); // false
}
}
Using Integer.parseInt()
and Double.parseDouble()
to check for numeric strings.
Method 2: Using Regular Expressions (Regex)
Regular expressions offer a powerful and flexible way to define complex patterns for numeric strings. This method is excellent for enforcing specific formats (e.g., only positive integers, numbers with a fixed number of decimal places, or specific currency formats). While potentially more complex to write, regex can be very efficient once compiled.
import java.util.regex.Pattern;
public class RegexNumericCheck {
// Pattern for integers (positive or negative)
private static final Pattern INTEGER_PATTERN = Pattern.compile("-?\\d+");
// Pattern for floating-point numbers (positive or negative, optional decimal part, optional scientific notation)
private static final Pattern DOUBLE_PATTERN = Pattern.compile("-?(\\d+\\.?\\d*|\\.\\d+)([eE][-+]?\\d+)?");
public static boolean isIntegerRegex(String str) {
if (str == null || str.isEmpty()) {
return false;
}
return INTEGER_PATTERN.matcher(str).matches();
}
public static boolean isDoubleRegex(String str) {
if (str == null || str.isEmpty()) {
return false;
}
return DOUBLE_PATTERN.matcher(str).matches();
}
public static void main(String[] args) {
System.out.println("Is '123' an integer (regex)? " + isIntegerRegex("123")); // true
System.out.println("Is '-45' an integer (regex)? " + isIntegerRegex("-45")); // true
System.out.println("Is '123.45' an integer (regex)? " + isIntegerRegex("123.45")); // false
System.out.println("Is 'abc' an integer (regex)? " + isIntegerRegex("abc")); // false
System.out.println("\nIs '3.14' a double (regex)? " + isDoubleRegex("3.14")); // true
System.out.println("Is '-0.5' a double (regex)? " + isDoubleRegex("-0.5")); // true
System.out.println("Is '100' a double (regex)? " + isDoubleRegex("100")); // true
System.out.println("Is '1.23e-5' a double (regex)? " + isDoubleRegex("1.23e-5")); // true
System.out.println("Is 'hello' a double (regex)? " + isDoubleRegex("hello")); // false
System.out.println("Is '.' a double (regex)? " + isDoubleRegex(".")); // false (needs at least one digit)
System.out.println("Is '.5' a double (regex)? " + isDoubleRegex(".5")); // true
}
}
Using regular expressions to validate numeric strings.
The DOUBLE_PATTERN
regex "-?(\\d+\\.?\\d*|\\.\\d+)([eE][-+]?\\d+)?"
is quite comprehensive. Let's break it down:
-?
: Optional negative sign.(\\d+\\.?\\d*|\\.\\d+)
: Matches either:\\d+\\.?\\d*
: One or more digits, optionally followed by a decimal point and zero or more digits (e.g., "123", "123.", "123.45").|\\.\\d+
: OR a decimal point followed by one or more digits (e.g., ".5").
([eE][-+]?\\d+)?
: Optional scientific notation (e.g., "e-5", "E+10").
Method 3: Character-by-Character Check
For simple integer checks, iterating through the string and verifying each character can be an efficient approach, especially if you want to avoid exceptions or regex overhead. This method gives you fine-grained control over what characters are allowed.
public class CharByCharNumericCheck {
public static boolean isPositiveInteger(String str) {
if (str == null || str.isEmpty()) {
return false;
}
for (int i = 0; i < str.length(); i++) {
if (!Character.isDigit(str.charAt(i))) {
return false;
}
}
return true;
}
public static boolean isSignedInteger(String str) {
if (str == null || str.isEmpty()) {
return false;
}
int i = 0;
if (str.charAt(0) == '-') {
i = 1; // Skip the negative sign
if (str.length() == 1) { // String is just "-"
return false;
}
}
for (; i < str.length(); i++) {
if (!Character.isDigit(str.charAt(i))) {
return false;
}
}
return true;
}
public static void main(String[] args) {
System.out.println("Is '123' a positive integer? " + isPositiveInteger("123")); // true
System.out.println("Is '-45' a positive integer? " + isPositiveInteger("-45")); // false
System.out.println("Is 'abc' a positive integer? " + isPositiveInteger("abc")); // false
System.out.println("\nIs '123' a signed integer? " + isSignedInteger("123")); // true
System.out.println("Is '-45' a signed integer? " + isSignedInteger("-45")); // true
System.out.println("Is '-' a signed integer? " + isSignedInteger("-")); // false
System.out.println("Is '12.3' a signed integer? " + isSignedInteger("12.3")); // false
}
}
Manual character-by-character check for integers.
try-catch
blocks.Method 4: Using Apache Commons Lang's StringUtils.isNumeric()
If you're already using the Apache Commons Lang library in your project, it provides a convenient utility method StringUtils.isNumeric()
. However, it's important to understand its definition of "numeric".
import org.apache.commons.lang3.StringUtils;
public class ApacheCommonsNumericCheck {
public static void main(String[] args) {
System.out.println("StringUtils.isNumeric('123'): " + StringUtils.isNumeric("123")); // true
System.out.println("StringUtils.isNumeric('-123'): " + StringUtils.isNumeric("-123")); // false (doesn't allow sign)
System.out.println("StringUtils.isNumeric('123.45'): " + StringUtils.isNumeric("123.45")); // false (doesn't allow decimal)
System.out.println("StringUtils.isNumeric(''): " + StringUtils.isNumeric("")); // false
System.out.println("StringUtils.isNumeric(null): " + StringUtils.isNumeric(null)); // false
System.out.println("StringUtils.isNumeric(' '): " + StringUtils.isNumeric(" ")); // false
}
}
Using Apache Commons Lang's StringUtils.isNumeric()
.
StringUtils.isNumeric()
returns true
only if the string contains only unicode digits. It does not handle negative signs, decimal points, or scientific notation. For more comprehensive checks, Apache Commons Lang also offers StringUtils.isNumericSpace()
(allows spaces) and StringUtils.isParsable()
(which uses Double.parseDouble()
internally).Performance Considerations
The performance of these methods can vary, especially when dealing with a large number of strings or very long strings:
Integer.parseInt()
/Double.parseDouble()
: Generally fast for valid numbers. Can be slower if manyNumberFormatException
s are thrown, as exception handling has overhead.- Regular Expressions: Compiling the pattern once (as shown with
Pattern.compile()
) makes subsequentmatcher().matches()
calls very efficient. Performance is good for complex patterns, but can be slower than simple character checks for very basic cases. - Character-by-Character: Often the fastest for simple integer checks as it avoids object creation and exception handling. However, it requires manual implementation for each numeric type.
- Apache Commons Lang: Performance is comparable to its underlying implementation (e.g.,
isParsable()
usesDouble.parseDouble()
).
For most applications, the performance difference is negligible. Prioritize readability and correctness unless profiling reveals a bottleneck.