java进阶(三)
在Java开发中,文本读取、字符串处理、正则匹配是日常开发最频繁的操作。绝大多数业务场景,比如参数校验、文本解析、日志提取、用户输入处理,都离不开四个核心类:
-
String:字符串存储与基础操作核心类
-
Scanner:流式数据扫描器,用于读取输入、解析文本
-
Pattern:正则表达式编译类,定义匹配规则
-
Matcher:正则匹配执行类,实现查找、匹配、替换
一、String 类:字符串核心处理类
1. 核心特性(面试高频)
String 是 不可变字符串,被 final 修饰,底层存储为字符数组(JDK9+ 改为字节数组)。每次对 String 进行修改(拼接、截取、替换),都会生成新字符串,原字符串不会改变。
优势:线程安全、字符串常量池复用、哈希值不可变;劣势:频繁修改效率低(推荐 StringBuilder/StringBuffer)。
2. 高频常用方法
涵盖开发90%字符串场景:判断、截取、替换、分割、转换、去空
-
判断:equals()、isEmpty()、contains()、startsWith()、endsWith()
-
截取:substring()、charAt()
-
修改:replace()、trim()、toLowerCase()、toUpperCase()
-
分割:split()
-
转换:valueOf()、getBytes()、toCharArray()
3. String 完整实战代码
/**
* String 类常用方法实战
*/
public class StringDemo {
public static void main(String[] args) {
String str = " Hello Java Text ";
// 1. 去首尾空格
String trimStr = str.trim();
System.out.println("去空格:" + trimStr); // Hello Java Text
// 2. 判断是否为空、包含字符、首尾匹配
System.out.println("是否为空:" + str.isEmpty()); // false
System.out.println("是否包含Java:" + trimStr.contains("Java")); // true
System.out.println("是否以Hello开头:" + trimStr.startsWith("Hello")); // true
System.out.println("是否以Text结尾:" + trimStr.endsWith("Text")); // true
// 3. 字符串截取
System.out.println("截取前5位:" + trimStr.substring(0, 5)); // Hello
System.out.println("获取下标6字符:" + trimStr.charAt(6)); // J
// 4. 字符串替换
String replaceStr = trimStr.replace("Java", "Java正则");
System.out.println("替换后:" + replaceStr); // Hello Java正则 Text
// 5. 字符串分割
String[] splitArr = trimStr.split(" ");
System.out.println("分割结果:");
for (String s : splitArr) {
System.out.println(s);
}
// 6. 大小写转换
System.out.println("大写:" + trimStr.toUpperCase());
System.out.println("小写:" + trimStr.toLowerCase());
// 7. 类型转换
int num = 123;
String numStr = String.valueOf(num); // 数字转字符串
System.out.println("数字转字符串:" + numStr);
}
}
二、Scanner 类:文本/输入扫描解析器
Scanner 是 Java 提供的流式扫描工具,核心作用是:读取控制台输入、读取文件文本、按规则分割解析字符串,相比 BufferedReader,用法更简单,适合轻量级文本解析。
1. 核心常用方法
-
next():读取单个字符串(空格/换行截断)
-
nextLine():读取整行字符串(包含空格,换行截断)
-
nextInt()/nextDouble():读取指定类型数据
-
useDelimiter():自定义分隔符(核心高级用法)
-
hasNext():判断是否还有下一个数据
2. 避坑重点
nextInt() 和 nextLine() 混用bug:nextInt() 只会读取数字,会残留换行符,导致后续 nextLine() 直接读取空值。解决方案:读取数字后手动吸收换行符。
3. Scanner 完整实战代码
import java.util.Scanner;
/**
* Scanner 类实战:控制台输入 + 自定义文本解析
*/
public class ScannerDemo {
public static void main(String[] args) {
// 1. 基础控制台输入
Scanner scanner = new Scanner(System.in);
System.out.print("请输入姓名:");
String name = scanner.nextLine();
System.out.print("请输入年龄:");
// 解决混用bug:读取数字后吸收换行
int age = scanner.nextInt();
scanner.nextLine();
System.out.println("姓名:" + name + ",年龄:" + age);
// 2. 高级用法:自定义分隔符解析字符串
String text = "张三,20,男;李四,22,女;王五,21,男";
Scanner textScanner = new Scanner(text);
// 自定义分隔符:逗号、分号
textScanner.useDelimiter("[,;]");
System.out.println("\n=====自定义分隔符解析文本=====");
while (textScanner.hasNext()) {
System.out.print(textScanner.next() + "\t");
}
// 关闭流
scanner.close();
textScanner.close();
}
}
三、Pattern + Matcher 类:Java正则核心
很多新手直接用 String 的 split()、replaceAll() 做正则匹配,底层其实都是调用了 Pattern 和 Matcher。
核心关系:
-
Pattern:正则规则编译类,将正则字符串编译成匹配模板(可复用,性能更高)
-
Matcher:匹配执行器,绑定文本和Pattern,实现精准匹配、查找、分组、替换
适用场景:复杂文本提取、手机号/邮箱/身份证校验、日志关键字提取、批量文本替换。
1. 核心方法说明
Pattern 核心方法
-
compile(String regex):编译正则表达式
-
matcher(CharSequence input):创建匹配器
-
matches():全局匹配(整个文本是否符合规则)
Matcher 核心方法
-
matches():全局匹配
-
find():查找下一个匹配的子串
-
group():获取匹配结果,支持分组获取
-
replaceAll():全局替换匹配内容
2. Pattern + Matcher 完整实战代码
包含:手机号校验、分组提取、关键字替换、批量查找四大高频场景
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Pattern + Matcher 正则实战
* 场景:手机号校验、分组提取、文本替换、关键字查找
*/
public class PatternMatcherDemo {
public static void main(String[] args) {
// 正则1:国内手机号正则
String phoneRegex = "^1[3-9]\\d{9}$";
// 正则2:提取文本中的数字
String numRegex = "\\d+";
// 正则3:匹配邮箱
String emailRegex = "\\w+@\\w+\\.\\w+";
// 1. 全局匹配:手机号校验
Pattern phonePattern = Pattern.compile(phoneRegex);
String phone1 = "13812345678";
String phone2 = "12345678901";
System.out.println("手机号1是否合法:" + phonePattern.matcher(phone1).matches()); // true
System.out.println("手机号2是否合法:" + phonePattern.matcher(phone2).matches()); // false
// 2. 批量查找:提取文本中所有数字
String content = "订单号:20260619,金额:99.9元,数量:5件";
Pattern numPattern = Pattern.compile(numRegex);
Matcher numMatcher = numPattern.matcher(content);
System.out.println("\n=====提取文本中所有数字=====");
while (numMatcher.find()) {
System.out.println("匹配到数字:" + numMatcher.group());
}
// 3. 分组匹配:提取用户名和邮箱后缀
String emailContent = "测试邮箱:test123@qq.com,工作邮箱:java@163.com";
Pattern emailPattern = Pattern.compile("(\\w+)@(\\w+\\.\\w+)");
Matcher emailMatcher = emailPattern.matcher(emailContent);
System.out.println("\n=====邮箱分组提取=====");
while (emailMatcher.find()) {
// group(1):第一组内容(用户名),group(2):第二组内容(域名)
System.out.println("用户名:" + emailMatcher.group(1) + ",域名:" + emailMatcher.group(2));
}
// 4. 正则替换:脱敏手机号
String userPhone = "用户手机号:13812345678";
String desensitize = phonePattern.matcher(userPhone).replaceAll("138****5678");
System.out.println("\n手机号脱敏结果:" + desensitize);
}
}
四、四大类综合实战:文本解析工具
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 综合实战:文本数据解析与校验工具
*/
public class TextAllDemo {
public static void main(String[] args) {
// 原始文本数据
String data = "用户:小明,电话:13966668888,邮箱:xiaoming@163.com;\n" +
"用户:小红,电话:12345678901,邮箱:xiaohong@qq.com";
// 1. Scanner解析每行数据
Scanner scanner = new Scanner(data);
String phoneRegex = "^1[3-9]\\d{9}$";
Pattern pattern = Pattern.compile(phoneRegex);
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
// 截取手机号片段
String phone = line.split("电话:")[1].split(",")[0];
// 正则校验
Matcher matcher = pattern.matcher(phone);
if (matcher.matches()) {
System.out.println("合法用户数据:" + line);
} else {
System.out.println("非法手机号,数据过滤:" + line);
}
}
scanner.close();
}
}
五、核心总结与开发建议
1. 各类使用场景选择
-
简单字符串操作:优先使用 String 自带方法(简洁高效)
-
读取控制台/自定义文本解析:使用 Scanner(轻量易用)
-
复杂正则匹配、分组提取、批量解析:必须用 Pattern + Matcher(性能远优于 String 正则方法)
2. 性能优化要点
-
Pattern 支持复用,不要在循环内重复 compile,避免频繁创建对象
-
大量字符串拼接,禁止直接用 +,使用 StringBuilder
-
Scanner 使用完毕必须关闭,避免IO资源泄漏
3. 常见避坑
-
String 不可变,修改操作必生成新对象
-
Scanner nextInt/nextLine 混用残留换行符问题
-
正则匹配区分 全局匹配(matches) 和 局部查找(find)
更多推荐



所有评论(0)