1. 概述

本文将介绍在Java中检查字符串是否包含数字的多种方法。首先会使用JDK原生API实现,然后展示如何借助Guava和Apache Commons Lang等第三方库完成相同目标。

2. 问题说明

我们的核心目标是判断字符串是否包含数字。需要创建的方法遵循以下规则:

  • ✅ 当字符串包含数字时返回true
  • ❌ 当字符串不包含数字时返回false

重要前提:为避免重复样板代码,我们假设输入字符串均为非空非null值。实际测试用例会覆盖边界情况。

3. 使用String类

String类提供了多个实用方法可用于数字检测,下面逐一分析。

3.1. String#matches方法

matches()方法通过正则表达式匹配字符串内容。核心思路是定义能表示"包含数字"的正则表达式:

static boolean checkUsingMatchesMethod(String input) {
    return input.matches(".*\\d.*");
}

正则表达式解析:

  • .* 匹配任意字符(除换行符外)零次或多次
  • \\d 匹配单个数字(等价于[0-9]

⚠️ 注意:\\d[0-9]效果完全相同,可根据团队规范选择。

测试用例验证:

public class StrContainsNumberUtilsUnitTest {

    private static final String INPUT_WITH_NUMBERS = "We hope 2024 will be great";
    private static final String INPUT_WITHOUT_NUMBERS = "Hello world";

    @Test
    public void givenInputString_whenUsingMatchesMethod_ThenCheck() {
        assertTrue(StrContainsNumberUtils.checkUsingMatchesMethod(INPUT_WITH_NUMBERS));
        assertFalse(StrContainsNumberUtils.checkUsingMatchesMethod(INPUT_WITHOUT_NUMBERS));
        assertFalse(StrContainsNumberUtils.checkUsingMatchesMethod(""));
        assertFalse(StrContainsNumberUtils.checkUsingMatchesMethod(null));
    }
}

3.2. String#replaceAll方法

replaceAll()方法通过正则替换实现检测。核心思路是移除所有数字后比较字符串长度:

static boolean checkUsingReplaceAllMethod(String input) {
    String result = input.replaceAll("\\d", "");
    return result.length() != input.length();
}

工作原理:

  1. 用空字符串替换所有数字字符
  2. 比较处理前后字符串长度
  3. 长度变化说明存在数字

💡 相比matches()方法,此方案稍显繁琐,但逻辑同样可靠。

测试验证:

@Test
public void givenInputString_whenUsingReplaceAllMethod_ThenCheck() {
    assertTrue(StrContainsNumberUtils.checkUsingReplaceAllMethod(INPUT_WITH_NUMBERS));
    assertFalse(StrContainsNumberUtils.checkUsingReplaceAllMethod(INPUT_WITHOUT_NUMBERS));
    assertFalse(StrContainsNumberUtils.checkUsingReplaceAllMethod(""));
    assertFalse(StrContainsNumberUtils.checkUsingReplaceAllMethod(null));
}

4. 使用Pattern类

Pattern类提供更灵活的正则操作方式。复用之前的正则表达式:

static boolean checkUsingPatternClass(String input) {
    return Pattern.compile(".*\\d.*")
      .matcher(input)
      .matches();
}

执行流程:

  1. compile() 编译正则表达式
  2. matcher() 创建匹配器
  3. matches() 执行匹配检测

🚀 优势:预编译正则表达式可提升重复调用性能。

测试用例:

@Test
public void givenInputString_whenUsingPatternClass_ThenCheck() {
    assertTrue(StrContainsNumberUtils.checkUsingPatternClass(INPUT_WITH_NUMBERS));
    assertFalse(StrContainsNumberUtils.checkUsingPatternClass(INPUT_WITHOUT_NUMBERS));
    assertFalse(StrContainsNumberUtils.checkUsingPatternClass(""));
    assertFalse(StrContainsNumberUtils.checkUsingPatternClass(null));
}

5. 使用Character#isDigit方法

通过遍历字符逐个检测,简单粗暴但有效:

static boolean checkUsingIsDigitMethod(String input) {
   for (char c : input.toCharArray()) {
      if (Character.isDigit(c)) {
         return true;
      }
   }
   return false;
}

特点:

  • ✅ 零依赖,纯JDK实现
  • ✅ 遇到首个数字立即返回,性能较好
  • ❌ 代码量稍多

测试验证:

@Test
public void givenInputString_whenUsingIsDigitMethod_ThenCheck() {
    assertTrue(StrContainsNumberUtils.checkUsingIsDigitMethod(INPUT_WITH_NUMBERS));
    assertFalse(StrContainsNumberUtils.checkUsingIsDigitMethod(INPUT_WITHOUT_NUMBERS));
    assertFalse(StrContainsNumberUtils.checkUsingIsDigitMethod(""));
    assertFalse(StrContainsNumberUtils.checkUsingIsDigitMethod(null));
}

6. 使用Stream API

Java 8的Stream API提供函数式解决方案:

static boolean checkUsingStreamApi(String input) {
    return input.chars()
      .anyMatch(Character::isDigit);
}

关键点:

  • chars() 将字符串转为IntStream
  • anyMatch() 检查是否存在数字字符
  • 方法引用Character::isDigit提升可读性

💡 适合熟悉函数式编程的开发者,代码简洁优雅。

测试用例:

@Test
public void givenInputString_whenUsingStreamApi_ThenCheck() {
    assertTrue(StrContainsNumberUtils.checkUsingStreamApi(INPUT_WITH_NUMBERS));
    assertFalse(StrContainsNumberUtils.checkUsingStreamApi(INPUT_WITHOUT_NUMBERS));
    assertFalse(StrContainsNumberUtils.checkUsingStreamApi(""));
    assertFalse(StrContainsNumberUtils.checkUsingStreamApi(null));
}

7. 使用Apache Commons Lang

添加依赖(Maven):

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

使用StringUtils工具类:

static boolean checkUsingApacheCommonsLang(String input) {
    String result = StringUtils.getDigits(input);
    return result != null && !result.isEmpty();
}

实现原理:

  • getDigits() 提取字符串中的所有数字
  • 检查结果字符串是否非空

⚠️ 注意:需处理null返回值(当输入为null时)

测试验证:

@Test
public void givenInputString_whenUsingApacheCommonsLang_ThenCheck() {
    assertTrue(StrContainsNumberUtils.checkUsingApacheCommonsLang(INPUT_WITH_NUMBERS));
    assertFalse(StrContainsNumberUtils.checkUsingApacheCommonsLang(INPUT_WITHOUT_NUMBERS));
    assertFalse(StrContainsNumberUtils.checkUsingApacheCommonsLang(""));
    assertFalse(StrContainsNumberUtils.checkUsingApacheCommonsLang(null));
}

8. 使用Guava

添加依赖(Maven):

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.0.1-jre</version>
</dependency>

使用CharMatcher实现:

static boolean checkUsingGuava(String input) {
    String result = CharMatcher.forPredicate(Character::isDigit)
      .retainFrom(input);
    return !result.isEmpty();
}

核心逻辑:

  • forPredicate() 创建数字字符匹配器
  • retainFrom() 保留所有数字字符
  • 检查结果是否为空

🚀 优势:链式调用流畅,代码可读性高。

测试用例:

@Test
public void givenInputString_whenUsingGuava_ThenCheck() {
    assertTrue(StrContainsNumberUtils.checkUsingGuava(INPUT_WITH_NUMBERS));
    assertFalse(StrContainsNumberUtils.checkUsingGuava(INPUT_WITHOUT_NUMBERS));
    assertFalse(StrContainsNumberUtils.checkUsingGuava(""));
    assertFalse(StrContainsNumberUtils.checkUsingGuava(null));
}

9. 总结

本文系统介绍了在Java中检测字符串数字的7种方案:

方案分类 具体实现 优势 适用场景
JDK原生 String.matches() 简洁直接 简单场景
String.replaceAll() 逻辑直观 需要额外处理时
Pattern类 性能更优 重复匹配场景
Character.isDigit() 零依赖 基础环境
Stream API 函数式风格 Java 8+项目
第三方库 Apache Commons Lang 功能丰富 已引入库的项目
Guava 链式调用 已使用Guava的项目

选择建议:

  • ✅ 新项目优先使用Stream API(简洁现代)
  • ✅ 性能敏感场景用Pattern类(预编译优化)
  • ✅ 已有第三方库直接使用对应工具类
  • ❌ 避免重复造轮子,善用成熟库

完整代码示例见GitHub仓库


原始标题:Check if a String Contains a Number Value in Java