杰瑞科技汇

Java字符串如何判断是否为数字?

最简单但有限的方法:Double.parseDouble()Integer.parseInt()

这是最直观、最简单的方法,适用于基本数字格式。

Java字符串如何判断是否为数字?-图1
(图片来源网络,侵删)

原理:尝试将 String 解析为 doubleint,如果解析失败(即字符串不是合法的数字格式),会抛出 NumberFormatException 异常,我们可以利用这个异常来判断。

示例代码

public class NumberUtils {
    // 判断是否为整数
    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) {
        String intStr1 = "123";
        String intStr2 = "123.45";
        String intStr3 = "abc";
        String intStr4 = ""; // 空字符串
        String intStr5 = null;
        System.out.println("'" + intStr1 + "' is an integer? " + isInteger(intStr1)); // true
        System.out.println("'" + intStr2 + "' is an integer? " + isInteger(intStr2)); // false
        System.out.println("'" + intStr3 + "' is an integer? " + isInteger(intStr3)); // false
        System.out.println("'" + intStr4 + "' is an integer? " + isInteger(intStr4)); // false
        System.out.println("null is an integer? " + isInteger(intStr5)); // false
        System.out.println("------------------------------------");
        String doubleStr1 = "123.45";
        String doubleStr2 = "123";
        String doubleStr3 = "1.23e10"; // 科学计数法
        String doubleStr4 = " -123.45 "; // 带空格
        System.out.println("'" + doubleStr1 + "' is a double? " + isDouble(doubleStr1)); // true
        System.out.println("'" + doubleStr2 + "' is a double? " + isDouble(doubleStr2)); // true
        System.out.println("'" + doubleStr3 + "' is a double? " + isDouble(doubleStr3)); // true
        System.out.println("'" + doubleStr4 + "' is a double? " + isDouble(doubleStr4)); // false (因为parseDouble不处理前后空格)
    }
}

优点

  • 代码简单:易于理解和实现。
  • 功能强大Double.parseDouble() 支持整数、小数、科学计数法(如 23e10)、正负号等。

缺点

  • 性能稍差:异常处理机制(try-catch)在 Java 中是有性能开销的,如果需要频繁判断,这会成为瓶颈。
  • 对空格敏感" 123 " 这样的字符串会返回 false,因为它不希望解析前后有空格。
  • 范围限制:对于 Integer.parseInt(),如果数字超出 int 的范围(约 ±21亿),会抛出异常,返回 false
  • 不够精确:无法区分 "123" 是整数还是浮点数。

性能更优的方法:正则表达式

如果你需要在一个循环中大量判断字符串,或者想更精确地控制数字的格式,正则表达式是更好的选择。

原理:定义一个匹配数字模式的正则表达式,然后用 String.matches() 方法去匹配。

示例代码

public class RegexNumberUtils {
    // 判断是否为整数(包括正负号)
    public static boolean isIntegerByRegex(String str) {
        if (str == null) {
            return false;
        }
        // ^[+-]?\\d+$  解释:
        // ^       字符串开始
        // [+-]?   可选的正号或负号
        // \\d+    一个或多个数字 (0-9)
        // $       字符串结束
        return str.matches("^[+-]?\\d+$");
    }
    // 判断是否为浮点数(包括正负号、小数点、科学计数法)
    public static boolean isDoubleByRegex(String str) {
        if (str == null) {
            return false;
        }
        // ^[+-]?\\d+(\\.\\d+)?([eE][+-]?\\d+)?$ 解释:
        // ^[+-]?\\d+            可选正负号 + 一个或多个整数部分
        // (\\.\\d+)?            可选的小数部分 (一个点 + 一个或多个数字)
        // ([eE][+-]?\\d+)?      可选的科学计数法部分 (e/E + 可选正负号 + 一个或多个数字)
        // $
        return str.matches("^[+-]?\\d+(\\.\\d+)?([eE][+-]?\\d+)?$");
    }
    public static void main(String[] args) {
        String num1 = "123";
        String num2 = "-456";
        String num3 = "+789";
        String num4 = "123.45";
        String num5 = "1.23e10";
        String num6 = "1.23E-5";
        String num7 = "abc";
        String num8 = "123.";
        System.out.println("Using Regex:");
        System.out.println("'" + num1 + "' is a number? " + isDoubleByRegex(num1)); // true
        System.out.println("'" + num2 + "' is a number? " + isDoubleByRegex(num2)); // true
        System.out.println("'" + num3 + "' is a number? " + isDoubleByRegex(num3)); // true
        System.out.println("'" + num4 + "' is a number? " + isDoubleByRegex(num4)); // true
        System.out.println("'" + num5 + "' is a number? " + isDoubleByRegex(num5)); // true
        System.out.println("'" + num6 + "' is a number? " + isDoubleByRegex(num6)); // true
        System.out.println("'" + num7 + "' is a number? " + isDoubleByRegex(num7)); // false
        System.out.println("'" + num8 + "' is a number? " + isDoubleByRegex(num8)); // false (根据我们的正则,.后面必须有数字)
    }
}

优点

  • 性能高:正则表达式匹配通常比异常捕获快,尤其是在循环中。
  • 灵活性强:可以精确控制匹配的格式,例如只匹配特定格式的数字。
  • 不依赖异常:避免了异常处理的性能开销。

缺点

  • 正则表达式复杂:对于复杂的数字格式(如科学计数法),正则表达式会变得难以阅读和维护。
  • 需要学习成本:需要熟悉正则表达式的语法。

最严谨的方法:Apache Commons Lang NumberUtils

在实际项目中,强烈推荐使用成熟的第三方库,Apache Commons Lang 是一个非常流行的 Java 工具库,其中的 NumberUtils 类提供了非常完善的数字判断功能。

依赖: 你需要添加 Maven 依赖:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version> <!-- 使用最新版本 -->
</dependency>

核心方法

  • NumberUtils.isParsable(String str): 判断字符串是否可以被解析为任何一种 Java 数字类型(int, long, float, double 等)。这是最常用、最推荐的方法
  • NumberUtils.isCreatable(String str): 功能与 isParsable 几乎一样,官方文档建议优先使用 isParsable

示例代码

import org.apache.commons.lang3.math.NumberUtils;
public class CommonsLangNumberUtils {
    public static void main(String[] args) {
        String str1 = "123";
        String str2 = "123.45";
        String str3 = "1,234"; // 千位分隔符,NumberUtils.isParsable() 返回 false
        String str4 = "1.23e10";
        String str5 = " -123.45 ";
        String str6 = "abc";
        String str7 = ""; // 空字符串
        String str8 = null;
        // NumberUtils.isParsable() 是最推荐的方法
        // 它能处理整数、小数、科学计数法、正负号
        // 但不能处理带空格或千位分隔符的字符串
        System.out.println("Using Apache Commons Lang NumberUtils.isParsable():");
        System.out.println("'" + str1 + "' is parsable? " + NumberUtils.isParsable(str1)); // true
        System.out.println("'" + str2 + "' is parsable? " + NumberUtils.isParsable(str2)); // true
        System.out.println("'" + str3 + "' is parsable? " + NumberUtils.isParsable(str3)); // false
        System.out.println("'" + str4 + "' is parsable? " + NumberUtils.isParsable(str4)); // true
        System.out.println("'" + str5 + "' is parsable? " + NumberUtils.isParsable(str5)); // false (因为有空格)
        System.out.println("'" + str6 + "' is parsable? " + NumberUtils.isParsable(str6)); // false
        System.out.println("'' is parsable? " + NumberUtils.isParsable(str7)); // false
        System.out.println("null is parsable? " + NumberUtils.isParsable(str8)); // false
    }
}

优点

  • 功能强大且稳定:经过大量项目验证,非常可靠。
  • 代码简洁:一行代码搞定,无需自己写 try-catch 或正则表达式。
  • 可读性好NumberUtils.isParsable(str) 的意图非常明确。

缺点

  • 引入外部依赖:需要在项目中添加第三方库的依赖。

总结与推荐

方法 优点 缺点 适用场景
try-catch 简单直观,支持标准数字格式 性能开销,对空格敏感,范围限制 快速原型、简单判断、不追求极致性能
正则表达式 性能高,灵活可控 正则表达式复杂,有学习成本 需要大量循环判断,或需要自定义数字格式
NumberUtils.isParsable() 功能强大、稳定、代码简洁、可读性好 需要引入第三方库 (强烈推荐)生产环境、企业级应用

最终建议

  1. 如果你正在开发一个企业级或生产级的应用,请毫不犹豫地选择 Apache Commons Lang 的 NumberUtils.isParsable(),这是最专业、最可靠、最省心的方案。
  2. 如果你只是写一个小的工具类或学习示例,并且不想引入外部依赖,try-catch 方法 是一个不错的选择,简单直接。
  3. 如果你对性能有极高要求,或者需要匹配非常特殊、自定义的数字格式,那么可以考虑 正则表达式,但务必花时间写对和测试你的正则表达式。
分享:
扫描分享到社交APP
上一篇
下一篇