Java常用API全解:从Math到包装类,吃透开发必备工具

10 阅读19分钟

Java常用API全解:从Math到包装类,吃透开发必备工具

本文系统梳理Java开发中最常用的核心API,覆盖Math、System、Runtime、Object、包装类、正则表达式,结合实战案例、底层原理与避坑技巧,衔接前文面向对象进阶知识点,夯实Java工具类使用能力,后续将补充时间类相关内容。

一、Math类:数学运算工具类

Math类是Java中用于数学运算的工具类,位于java.lang包(无需导入),所有方法均为静态方法,直接通过Math.方法名()调用,无需创建对象,核心用于数值计算、取整、随机数等场景。Math类还包含多个常用静态常量(如圆周率π、自然常数e),满足日常数学运算需求。

1.1 核心常用方法(重点)

方法名方法说明示例返回结果
Math.abs(数值)取任意数值的绝对值(支持int、double等类型)Math.abs(-10)、Math.abs(-3.14)10、3.14
Math.ceil(double num)向上取整(返回大于等于参数的最小整数,结果为double类型)Math.ceil(3.1)、Math.ceil(-3.1)4.0、-3.0
Math.floor(double num)向下取整(返回小于等于参数的最大整数,结果为double类型)Math.floor(3.9)、Math.floor(-3.9)3.0、-4.0
Math.round(double num)四舍五入取整(返回long类型,小数部分≥0.5向上取整,否则向下取整)Math.round(3.4)、Math.round(3.5)3、4
Math.max(数值1, 数值2)取两个数值中的最大值(支持同类型数值对比)Math.max(10, 20)、Math.max(3.14, 2.99)20、3.14
Math.min(数值1, 数值2)取两个数值中的最小值(支持同类型数值对比)Math.min(10, 20)、Math.min(3.14, 2.99)10、2.99
Math.random()生成[0.0, 1.0)之间的随机double值(左闭右开区间)Math.random()0.0~1.0之间的随机数(如0.356)
Math.pow(double a, double b)计算a的b次方(返回double类型)Math.pow(2, 3)、Math.pow(4, 0.5)8.0、2.0
Math.sqrt(double num)计算数值的平方根(返回double类型,参数需≥0)Math.sqrt(16)、Math.sqrt(2)4.0、1.4142...

1.2 常用静态常量

  • Math.PI:圆周率,值约为3.141592653589793

  • Math.E:自然常数,值约为2.718281828459045

1.3 实战案例:Math类综合使用

需求:生成1-100之间的随机整数,计算该整数的绝对值、平方根,以及与50的最大值、最小值,最后对结果四舍五入保留1位小数。

public class MathDemo {
    public static void main(String[] args) {
        // 1. 生成1-100之间的随机整数(Math.random()生成[0,1),扩大100倍后取整)
        int randomNum = (int) (Math.random() * 100 + 1);
        System.out.println("生成的随机整数:" + randomNum);
        
        // 2. 计算绝对值(此处演示,随机数已为正数)
        int absNum = Math.abs(randomNum);
        System.out.println("随机数的绝对值:" + absNum);
        
        // 3. 计算平方根(转换为double类型)
        double sqrtNum = Math.sqrt(randomNum);
        System.out.println("随机数的平方根:" + sqrtNum);
        
        // 4. 计算与50的最大值、最小值
        int maxNum = Math.max(randomNum, 50);
        int minNum = Math.min(randomNum, 50);
        System.out.println("与50的最大值:" + maxNum);
        System.out.println("与50的最小值:" + minNum);
        
        // 5. 四舍五入保留1位小数(先扩大10倍,四舍五入,再缩小10倍)
        double roundNum = Math.round(sqrtNum * 10) / 10.0;
        System.out.println("平方根四舍五入保留1位小数:" + roundNum);
        
        // 6. 演示圆周率和自然常数的使用
        System.out.println("圆周率π:" + Math.PI);
        System.out.println("自然常数e:" + Math.E);
    }
}

1.4 避坑点

  1. Math.ceil()、Math.floor()返回值是double类型,而非int类型,若需int类型,需手动强制转换(如(int)Math.ceil(3.1) → 4);

  2. Math.random()生成的是[0.0, 1.0)的左闭右开区间,生成1-n之间的随机整数,公式为:(int)(Math.random() * n + 1);

  3. Math.round()参数为double时,返回long类型,若需int类型,需强制转换,避免类型转换异常。

二、System类:系统相关工具类

System类位于java.lang包(无需导入),所有成员均为静态成员(静态方法、静态变量),核心用于获取系统信息、操作输入输出流、管理垃圾回收、获取当前时间等,是Java开发中高频使用的系统级工具类。

2.1 核心常用方法与变量

方法/变量名说明示例
System.out静态变量,对应标准输出流(控制台打印),常用println()、print()方法System.out.println("Hello Java")
System.in静态变量,对应标准输入流(从控制台读取输入),需配合Scanner使用Scanner sc = new Scanner(System.in)
System.err静态变量,对应标准错误输出流(打印错误信息,通常为红色)System.err.println("错误信息")
System.currentTimeMillis()返回当前系统时间戳(毫秒级),从1970-01-01 00:00:00 UTC开始计算,常用于计算程序执行时间System.currentTimeMillis()
System.nanoTime()返回当前系统时间戳(纳秒级),精度比currentTimeMillis()更高,适合计算短时间任务的执行耗时System.nanoTime()
System.gc()建议JVM执行垃圾回收(仅为建议,JVM不一定立即执行),回收未被引用的对象,释放内存System.gc()
System.exit(int status)终止当前Java虚拟机,status为0表示正常退出,非0表示异常退出System.exit(0)
System.arraycopy(源数组, 源起始索引, 目标数组, 目标起始索引, 复制长度)复制数组元素,效率比for循环复制更高,常用于数组拷贝场景System.arraycopy(arr1, 0, arr2, 0, 3)

2.2 实战案例:System类综合使用

需求:计算一段代码的执行耗时,拷贝数组,演示垃圾回收和系统退出的使用。

public class SystemDemo {
    public static void main(String[] args) {
        // 1. 计算代码执行耗时(毫秒级)
        long start = System.currentTimeMillis();
        
        // 模拟耗时操作:循环10000次
        for (int i = 0; i < 10000; i++) {
            Math.random();
        }
        
        long end = System.currentTimeMillis();
        System.out.println("循环执行耗时:" + (end - start) + "毫秒");
        
        // 2. 数组拷贝(使用System.arraycopy)
        int[] arr1 = {1, 2, 3, 4, 5};
        int[] arr2 = new int[5];
        // 拷贝arr1的前3个元素,从索引0开始,拷贝到arr2的索引0位置
        System.arraycopy(arr1, 0, arr2, 0, 3);
        System.out.print("拷贝后的arr2:");
        for (int num : arr2) {
            System.out.print(num + " "); // 输出:1 2 3 0 0
        }
        System.out.println();
        
        // 3. 演示垃圾回收(仅建议,JVM不一定立即执行)
        // 创建一个临时对象,使用后赋值为null,变为垃圾对象
        Object obj = new Object();
        obj = null;
        System.out.println("建议JVM执行垃圾回收");
        System.gc();
        
        // 4. 演示系统退出(注释后可正常执行后续代码,取消注释则终止程序)
        // System.out.println("程序即将退出");
        // System.exit(0);
        // System.out.println("这句话不会执行");
    }
}

2.3 避坑点

  1. System.currentTimeMillis()返回的是毫秒级时间戳,时区为UTC,若需转换为本地时间,需结合时间类(如Date、LocalDateTime)使用;

  2. System.gc()仅为“建议”JVM执行垃圾回收,不能强制JVM立即回收垃圾,垃圾回收的时机由JVM自主决定;

  3. System.arraycopy()拷贝时,需注意源数组、目标数组的长度和索引,避免数组越界异常(ArrayIndexOutOfBoundsException);

  4. System.exit(0)会直接终止虚拟机,后续代码不会执行,需谨慎使用(如在try-catch的finally中使用,会导致finally中后续代码无法执行)。

三、Runtime类:运行时环境工具类

Runtime类位于java.lang包(无需导入),用于获取当前Java虚拟机的运行时环境信息,如内存使用情况、处理器数量,还能执行系统命令、管理虚拟机进程。Runtime类是单例模式,不能通过new创建对象,需通过Runtime.getRuntime()方法获取唯一实例。

3.1 核心常用方法

方法名说明示例
Runtime.getRuntime()获取Runtime类的唯一实例(单例模式)Runtime runtime = Runtime.getRuntime()
totalMemory()返回JVM的总内存大小(字节),即JVM初始分配的内存总量runtime.totalMemory()
freeMemory()返回JVM当前的空闲内存大小(字节)runtime.freeMemory()
maxMemory()返回JVM能获取的最大内存大小(字节),超出该大小会抛出内存溢出异常(OutOfMemoryError)runtime.maxMemory()
availableProcessors()返回当前设备的处理器核心数,常用于多线程编程中设置线程数runtime.availableProcessors()
exec(String command)执行系统命令(如打开记事本、查看文件列表),返回Process对象,需处理异常runtime.exec("notepad.exe")(Windows打开记事本)
gc()与System.gc()功能一致,建议JVM执行垃圾回收runtime.gc()

3.2 实战案例:Runtime类综合使用

需求:获取JVM内存信息(总内存、空闲内存、最大内存),获取处理器核心数,执行系统命令(Windows打开记事本)。

import java.io.IOException;

public class RuntimeDemo {
    public static void main(String[] args) {
        // 1. 获取Runtime类的唯一实例
        Runtime runtime = Runtime.getRuntime();
        
        // 2. 获取JVM内存信息(转换为MB,1MB = 1024*1024字节)
        long totalMemory = runtime.totalMemory() / (1024 * 1024);
        long freeMemory = runtime.freeMemory() / (1024 * 1024);
        long maxMemory = runtime.maxMemory() / (1024 * 1024);
        
        System.out.println("JVM总内存:" + totalMemory + "MB");
        System.out.println("JVM空闲内存:" + freeMemory + "MB");
        System.out.println("JVM最大内存:" + maxMemory + "MB");
        System.out.println("当前设备处理器核心数:" + runtime.availableProcessors());
        
        // 3. 执行系统命令(Windows打开记事本,Linux/macOS需修改命令)
        try {
            System.out.println("打开记事本...");
            runtime.exec("notepad.exe");
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        // 4. 建议垃圾回收,查看回收后的空闲内存
        runtime.gc();
        long freeMemoryAfterGc = runtime.freeMemory() / (1024 * 1024);
        System.out.println("垃圾回收后的空闲内存:" + freeMemoryAfterGc + "MB");
    }
}

3.3 避坑点

  1. Runtime类是单例模式,只能通过getRuntime()方法获取实例,不能new创建,否则编译报错;

  2. exec()方法执行系统命令时,不同操作系统的命令不同(如Windows打开记事本是notepad.exe,macOS是open -a TextEdit),需注意跨平台兼容性;

  3. exec()方法会抛出IOException异常,必须处理(try-catch或throws);

  4. JVM内存信息(totalMemory、freeMemory等)是动态变化的,每次获取的结果可能不同,仅作参考。

四、Object类:所有类的父类

Object类位于java.lang包(无需导入),是Java中所有类的直接或间接父类(若一个类没有显式继承其他类,默认继承Object类)。Object类定义了所有对象都具备的核心方法,子类可根据需求重写这些方法,实现个性化功能。

4.1 核心常用方法(重点,必须掌握)

4.1.1 equals(Object obj):判断两个对象是否相等

默认实现:Object类的equals()方法,本质是比较两个对象的内存地址(与==效果一致),即return this == obj;

重写场景:当需要判断两个对象的“内容相等”(而非内存地址相等)时,需重写equals()方法(如String类、包装类已重写)。

重写原则(必须遵守):

  1. 自反性:obj.equals(obj) → true;

  2. 对称性:若a.equals(b)为true,则b.equals(a)也为true;

  3. 传递性:若a.equals(b)为true,b.equals(c)为true,则a.equals(c)也为true;

  4. 一致性:多次调用obj.equals(obj2),结果始终一致(对象内容未修改的情况下);

  5. 非空性:obj.equals(null) → false。

4.1.2 hashCode():返回对象的哈希值

默认实现:Object类的hashCode()方法,返回对象的内存地址对应的整数(不同对象的哈希值一般不同)。

核心规则:equals()方法返回true的两个对象,hashCode()必须返回相同的值;equals()返回false的两个对象,hashCode()可以返回相同的值(但不推荐,会降低哈希表效率)

注意:重写equals()方法时,必须同时重写hashCode()方法,否则会违反上述规则,导致HashSet、HashMap等集合无法正常工作。

4.1.3 toString():返回对象的字符串表示

默认实现:Object类的toString()方法,返回格式为:类名@哈希值的十六进制(如com.xxx.ObjectDemo@1b6d3586),无实际意义。

重写场景:为了更直观地查看对象的属性信息,通常会重写toString()方法,返回对象的属性值(如自定义实体类)。

4.1.4 其他常用方法

  • getClass():返回对象的运行时类(Class对象),常用于反射编程,无法重写;

  • notify():唤醒当前对象的等待线程(多线程相关);

  • notifyAll():唤醒当前对象的所有等待线程(多线程相关);

  • wait():让当前线程进入等待状态(多线程相关),需在同步代码块中使用。

4.2 实战案例:重写Object类的核心方法

需求:自定义Student类,重写equals()、hashCode()、toString()方法,实现对象内容对比和直观打印。

import java.util.Objects;

// 自定义Student类,默认继承Object类
class Student {
    private String name;
    private int age;
    private String studentId;

    // 构造方法
    public Student(String name, int age, String studentId) {
        this.name = name;
        this.age = age;
        this.studentId = studentId;
    }

    // 重写toString()方法,返回对象属性信息
    @Override
    public String toString() {
        return "Student{name='" + name + "', age=" + age + ", studentId='" + studentId + "'}";
    }

    // 重写equals()方法,按姓名+学号判断对象是否相等
    @Override
    public boolean equals(Object o) {
        if (this == o) return true; // 内存地址相同,直接返回true
        if (o == null || getClass() != o.getClass()) return false; // 非同一类型,返回false
        Student student = (Student) o; // 强制转换
        // 比较核心属性(姓名、学号),年龄可根据需求决定是否参与比较
        return age == student.age && Objects.equals(name, student.name) && Objects.equals(studentId, student.studentId);
    }

    // 重写hashCode()方法,与equals()方法保持一致
    @Override
    public int hashCode() {
        return Objects.hash(name, age, studentId);
    }
}

// 测试类
public class ObjectDemo {
    public static void main(String[] args) {
        // 创建两个内容相同的Student对象
        Student s1 = new Student("张三", 20, "2024001");
        Student s2 = new Student("张三", 20, "2024001");
        Student s3 = new Student("李四", 21, "2024002");

        // 测试toString()方法
        System.out.println(s1); // 输出重写后的字符串:Student{name='张三', age=20, studentId='2024001'}
        System.out.println(s2);

        // 测试equals()方法
        System.out.println("s1.equals(s2):" + s1.equals(s2)); // true(内容相等)
        System.out.println("s1.equals(s3):" + s1.equals(s3)); // false(内容不同)
        System.out.println("s1.equals(null):" + s1.equals(null)); // false(非空性)

        // 测试hashCode()方法
        System.out.println("s1的hashCode:" + s1.hashCode());
        System.out.println("s2的hashCode:" + s2.hashCode()); // 与s1相同
        System.out.println("s3的hashCode:" + s3.hashCode()); // 与s1不同

        // 测试getClass()方法
        System.out.println("s1的运行时类:" + s1.getClass()); // class com.xxx.Student
    }
}

4.3 避坑点

  1. equals()与==的区别:==比较的是对象的内存地址(基本数据类型比较的是值),equals()默认比较内存地址,重写后可比较内容;

  2. 重写equals()必须重写hashCode(),否则会导致HashSet中无法去重(HashSet先通过hashCode()判断,再通过equals()判断);

  3. toString()方法重写后,打印对象时会自动调用,无需手动调用(如System.out.println(s1),本质是调用s1.toString());

  4. getClass()方法无法重写,若需判断对象类型,也可使用instanceof关键字(如s1 instanceof Student)。

五、包装类:基本数据类型的封装类

Java中基本数据类型(byte、short、int、long、float、double、char、boolean)不是对象,无法直接使用面向对象的特性(如调用方法、存储到集合中)。包装类是对基本数据类型的封装,将基本数据类型转换为对象,实现面向对象编程,同时提供了大量常用方法。

包装类与基本数据类型的对应关系(8种):

基本数据类型包装类(java.lang包,无需导入)
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

5.1 核心特性:自动装箱与自动拆箱

JDK 1.5+新增特性,无需手动转换基本数据类型与包装类,JVM自动完成转换,简化代码。

  • 自动装箱:基本数据类型 → 包装类(如int → Integer);

  • 自动拆箱:包装类 → 基本数据类型(如Integer → int)。

public class WrapperDemo1 {
    public static void main(String[] args) {
        // 自动装箱:int → Integer
        Integer num1 = 10; // 等价于:Integer num1 = Integer.valueOf(10);
        
        // 自动拆箱:Integer → int
        int num2 = num1; // 等价于:int num2 = num1.intValue();
        
        // 包装类对象可以为null(基本数据类型不能为null)
        Integer num3 = null;
        // int num4 = num3; // 报错:NullPointerException(空指针异常)
        
        // 包装类与基本数据类型比较(自动拆箱)
        System.out.println(num1 == 10); // true
        System.out.println(num1.equals(10)); // true(equals()重写,比较值)
    }
}

5.2 核心常用方法(以Integer、Character为例)

5.2.1 Integer类常用方法

方法名说明示例
Integer.valueOf(int i)将int类型转换为Integer对象(自动装箱底层调用此方法)Integer.valueOf(10) → 10
Integer.parseInt(String s)将字符串转换为int类型(字符串必须是纯数字,否则报错)Integer.parseInt("123") → 123
intValue()将Integer对象转换为int类型(自动拆箱底层调用此方法)new Integer(10).intValue() → 10
toString()将Integer对象转换为字符串new Integer(10).toString() → "10"
max(int a, int b)取两个int值的最大值(静态方法)Integer.max(10, 20) → 20
min(int a, int b)取两个int值的最小值(静态方法)Integer.min(10, 20) → 10

5.2.2 Character类常用方法

方法名说明示例
Character.valueOf(char c)将char类型转换为Character对象Character.valueOf('a') → 'a'
charValue()将Character对象转换为char类型new Character('a').charValue() → 'a'
isLetter(char c)判断字符是否为字母(大小写均可)Character.isLetter('A') → true;Character.isLetter('1') → false
isDigit(char c)判断字符是否为数字Character.isDigit('5') → true;Character.isDigit('a') → false
isUpperCase(char c)判断字符是否为大写字母Character.isUpperCase('A') → true;Character.isUpperCase('a') → false
isLowerCase(char c)判断字符是否为小写字母Character.isLowerCase('a') → true;Character.isLowerCase('A') → false
toUpperCase(char c)将字符转换为大写Character.toUpperCase('a') → 'A'
toLowerCase(char c)将字符转换为小写Character.toLowerCase('A') → 'a'

5.3 实战案例:包装类综合使用

需求:将字符串类型的数字转换为int类型,判断字符类型,实现数字与字符串的转换,演示自动装箱与拆箱。

public class WrapperDemo2 {
    public static void main(String[] args) {
        // 1. 字符串转int(常用场景:接收控制台输入的数字)
        String strNum = "12345";
        int num = Integer.parseInt(strNum);
        System.out.println("字符串转int:" + num);
        
        // 错误示例:字符串不是纯数字,转换报错
        // String str = "123a";
        // int errorNum = Integer.parseInt(str); // 报错:NumberFormatException
        
        // 2. int转字符串
        int num2 = 678;
        String strNum2 = Integer.toString(num2);
        System.out.println("int转字符串:" + strNum2 + ",类型:" + strNum2.getClass().getSimpleName());
        
        // 3. 字符类型判断
        char c1 = 'A';
        char c2 = '5';
        char c3 = 'b';
        System.out.println(c1 + "是字母?" + Character.isLetter(c1)); // true
        System.out.println(c2 + "是数字?" + Character.isDigit(c2)); // true
        System.out.println(c3 + "是小写字母?" + Character.isLowerCase(c3)); // true
        System.out.println("将" + c1 + "转为小写:" + Character.toLowerCase(c1)); // 'a'
        
        // 4. 自动装箱与拆箱的实际应用(存储到集合中)
        java.util.List<Integer> list = new java.util.ArrayList<>();
        list.add(10); // 自动装箱:int → Integer
        list.add(20);
        list.add(30);
        
        // 遍历集合,自动拆箱:Integer → int
        for (int n : list) {
            System.out.print(n + " "); // 输出:10 20 30
        }
    }
}

5.4 避坑点

  1. 包装类对象可以为null,基本数据类型不能为null,使用包装类时需注意空指针异常(如Integer num = null; int n = num; 会报错);

  2. Integer.parseInt(String s)方法,字符串必须是纯数字(可含正负号),否则会抛出NumberFormatException(数字格式异常);

  3. Integer缓存机制:Integer.valueOf(int i)方法,对-128~127之间的整数进行缓存,多次调用返回同一个对象(超出范围则创建新对象);

  4. 包装类的equals()方法已重写,比较的是值,而非内存地址;==比较的是内存地址(自动拆箱时除外)。

六、正则表达式:字符串匹配工具

正则表达式(Regular Expression)是一种用于匹配字符串的模式,可快速实现字符串的校验、查找、替换、分割等操作,Java中通过java.util.regex包下的Pattern类和Matcher类实现正则表达式的使用,是字符串处理的核心工具。

6.1 核心正则表达式语法(常用)

正则表达式由普通字符(如a、1、@)和特殊字符(元字符)组成,以下是开发中最常用的语法:

元字符说明示例
.匹配任意单个字符(除了换行符\n)"a.b"可匹配"aab"、"acb"、"a1b"
*匹配前面的字符0次或多次"a*b"可匹配"b"、"ab"、"aab"、"aaab"
+匹配前面的字符1次或多次"a+b"可匹配"ab"、"aab"、"aaab"(不能匹配"b")
?匹配前面的字符0次或1次"a?b"可匹配"b"、"ab"(不能匹配"aab")
{n}匹配前面的字符恰好n次"a{3}b"可匹配"aaab"(不能匹配"aab"、"aaaab")
{n,}匹配前面的字符至少n次"a{2,}b"可匹配"aab"、"aaab"、"aaaab"
{n,m}匹配前面的字符n~m次(包含n和m)"a{2,3}b"可匹配"aab"、"aaab"
[]匹配括号内的任意一个字符"[abc]"可匹配"a"、"b"、"c";"[0-9]"可匹配任意数字
[^]匹配括号内以外的任意一个字符"[^abc]"可匹配除"a"、"b"、"c"以外的任意字符
匹配字符串的开头"^abc"可匹配"abc123"(不能匹配"123abc")
$匹配字符串的结尾"abc$"可匹配"123abc"(不能匹配"abc123")
\d匹配任意数字(等价于[0-9])"a\d"可匹配"a1"、"a2"、"a3"
\D匹配任意非数字(等价于[^0-9])"a\D"可匹配"aa"、"ab"、"a@"
\w匹配字母、数字、下划线(等价于[a-zA-Z0-9_])"a\w"可匹配"a1"、"aa"、"a_"
\W匹配非字母、非数字、非下划线(等价于[^a-zA-Z0-9_])"a\W"可匹配"a@"、"a#"、"a "
\s匹配任意空白字符(空格、制表符、换行符等)"a\s"可匹配"a "、"a\t"(制表符)
\S匹配任意非空白字符"a\S"可匹配"a1"、"aa"、"a@"

6.2 开发中高频正则表达式模板

  • 手机号校验:^1[3-9]\d{9}$(11位,开头为13-9,后面跟9位数字);

  • 邮箱校验:^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$(支持字母、数字、下划线、中划线,支持多级域名);

  • 身份证号校验(18位):^\d{17}[\dXx]$(前17位为数字,最后一位为数字或X/x);

  • 用户名校验(4-16位,支持字母、数字、下划线,不能以数字开头):^[a-zA-Z_]\w{3,15}$

  • 密码校验(8-20位,包含大小写字母、数字、特殊符号至少两种):^(?![a-zA-Z]+$)(?![0-9]+$)(?![^a-zA-Z0-9]+$).{8,20}$

  • 纯数字校验(任意长度正整数):^\d+$

  • 中文校验(仅含中文,任意长度):^[\u4e00-\u9fa5]+$

  • URL校验(支持http/https):^(https?://)?([\da-z.-]+)\.([a-z.]{2,6})([/\w.-]*)*(/?)$

  • 日期校验(yyyy-MM-dd格式):^\d{4}-\d{2}-\d{2}$

6.3 Java中正则表达式的使用(Pattern与Matcher类)

Java中使用正则表达式,核心依赖java.util.regex.Patternjava.util.regex.Matcher两个类,无需手动导入(JDK自带),常用使用步骤:1. 编译正则表达式(Pattern.compile());2. 创建匹配器(pattern.matcher(目标字符串));3. 执行匹配、查找、替换等操作。

6.3.1 核心方法(重点)

类与方法说明示例
Pattern.compile(String regex)编译正则表达式,返回Pattern对象(线程安全,可复用)Pattern pattern = Pattern.compile("^1[3-9]\d{9}$")
pattern.matcher(String input)创建匹配器,关联目标字符串,返回Matcher对象Matcher matcher = pattern.matcher("13800138000")
matcher.matches()判断整个目标字符串是否完全匹配正则表达式(常用校验场景)matcher.matches() → true/false
matcher.find()查找目标字符串中是否包含匹配正则的子串(可多次调用)while(matcher.find()) { ... }
matcher.replaceAll(String replacement)将所有匹配正则的子串替换为指定字符串matcher.replaceAll("***")
Pattern.matches(String regex, String input)静态方法,简化写法,直接判断字符串是否匹配正则(无需创建Pattern和Matcher)Pattern.matches("^\d+$", "123") → true

6.4 实战案例:正则表达式综合使用

需求:实现常见字符串校验(手机号、邮箱、身份证号)、查找字符串中的数字、替换敏感字符(如手机号中间4位打码)。

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexDemo {
    public static void main(String[] args) {
        // 1. 字符串校验(手机号、邮箱、身份证号)
        String phone = "13800138000";
        String email = "test_123@163.com";
        String idCard = "11010119900307123X";
        
        // 手机号校验
        boolean isPhone = Pattern.matches("^1[3-9]\\d{9}$", phone);
        // 邮箱校验
        boolean isEmail = Pattern.matches("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$", email);
        // 身份证号校验(18位)
        boolean isIdCard = Pattern.matches("^\\d{17}[\\dXx]$", idCard);
        
        System.out.println("手机号校验:" + isPhone); // true
        System.out.println("邮箱校验:" + isEmail); // true
        System.out.println("身份证号校验:" + isIdCard); // true
        
        // 2. 查找字符串中的所有数字
        String str = "Java123编程456,正则789实战";
        Pattern numPattern = Pattern.compile("\\d+");
        Matcher numMatcher = numPattern.matcher(str);
        System.out.print("字符串中的数字:");
        while (numMatcher.find()) {
            // group()方法获取匹配到的子串
            System.out.print(numMatcher.group() + " "); // 输出:123 456 789
        }
        System.out.println();
        
        // 3. 替换敏感字符(手机号中间4位打码)
        String phone2 = "13912345678";
        Pattern phonePattern = Pattern.compile("(^1[3-9]\\d{2})(\\d{4})(\\d{4})$");
        Matcher phoneMatcher = phonePattern.matcher(phone2);
        // 分组替换,$1表示第一个分组,$2第二个分组,$3第三个分组
        String maskedPhone = phoneMatcher.replaceAll("$1****$3");
        System.out.println("打码后的手机号:" + maskedPhone); // 输出:139****5678
        
        // 4. 分割字符串(按任意空白字符分割)
        String str2 = "Java 正则 实战 2024";
        String[] arr = str2.split("\\s+");
        System.out.print("分割后的字符串数组:");
        for (String s : arr) {
            System.out.print(s + "|"); // 输出:Java|正则|实战|2024|
        }
    }
}

6.5 避坑点

  1. 正则表达式中的反斜杠\,在Java字符串中需转义,即写为\\(如\d在Java中需写为\\d),否则会被识别为转义字符报错;

  2. matches()方法是“全匹配”,必须整个字符串符合正则才返回true,若需“部分匹配”(包含子串),需使用find()方法;

  3. Pattern对象线程安全,可复用(如多次校验手机号,可只编译一次Pattern),Matcher对象非线程安全,不可跨线程使用;