当前位置: 首页 > news >正文

day15——Java常用API(二):常见算法、正则表达式与异常处理详解

文章目录

    • 一、常见算法详解
      • 1.1 排序算法
        • 冒泡排序
        • 选择排序
      • 1.2 查找算法
        • 二分查找
    • 二、正则表达式深入解析
      • 2.1 正则表达式基础
      • 2.2 正则表达式应用案例
        • 测试
        • 数据校验
        • 信息爬取
        • 文本处理
      • 2.3 高级技巧
    • 三、异常处理机制
      • 3.1 异常体系结构
      • 3.2 异常处理方式
        • 抛出异常(throws)
        • 捕获异常(try-catch)
      • 3.3 自定义异常
      • 3.4 异常处理最佳实践
    • 四、总结与应用场景
      • 4.1 算法应用场景
      • 4.2 正则表达式应用场景
      • 4.3 异常处理应用场景

本文将深入探讨Java中三大核心技术:常见算法、正则表达式和异常处理,帮助开发者掌握这些必备技能。

一、常见算法详解

1.1 排序算法

冒泡排序

原理:通过相邻元素比较和交换,每一轮将最大元素"冒泡"到数组末尾
关键步骤

  1. 确定轮数:数组长度-1
  2. 每轮比较次数:数组长度-当前轮数-1
  3. 相邻元素比较,顺序错误则交换
// 冒泡排序实现
public static void bubbleSort(int[] arr) {for (int i = 0; i < arr.length - 1; i++) {for (int j = 0; j < arr.length - i - 1; j++) {if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}
}
选择排序

原理:每轮选择一个固定位置元素,与后面元素比较找到最小元素并交换
关键步骤

  1. 确定轮数:数组长度-1
  2. 每轮从当前位置开始向后比较
  3. 找到最小元素索引并交换
// 选择排序实现
public static void selectionSort(int[] arr) {for (int i = 0; i < arr.length - 1; i++) {int minIndex = i;for (int j = i + 1; j < arr.length; j++) {if (arr[j] < arr[minIndex]) {minIndex = j;}}int temp = arr[i];arr[i] = arr[minIndex];arr[minIndex] = temp;}
}

1.2 查找算法

二分查找

前提:数组必须有序
原理:每次将查找范围缩小一半
步骤

  1. 定义左右边界(left, right)
  2. 计算中间位置 mid = (left + right) / 2
  3. 比较中间元素与目标值:
    • 目标值大:left = mid + 1
    • 目标值小:right = mid - 1
    • 相等:返回mid
  4. 循环直到left > right,未找到返回-1
// 二分查找实现
public static int binarySearch(int[] arr, int target) {int left = 0;int right = arr.length - 1;while (left <= right) {int mid = left + (right - left) / 2;if (arr[mid] == target) {return mid;} else if (arr[mid] < target) {left = mid + 1;} else {right = mid - 1;}}return -1;
}

在这里插入图片描述

二、正则表达式深入解析

2.1 正则表达式基础

核心作用

  1. 数据格式校验(如手机号、邮箱验证)
  2. 文本内容提取(爬取特定信息)
  3. 文本替换与分割

基础语法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

类别表达式说明
字符类[abc]匹配a、b或c
[^abc]匹配除a、b、c外的字符
[a-zA-Z]匹配任意字母
预定义字符.匹配任意单个字符
\d匹配数字[0-9]
\D匹配非数字
\s匹配空白字符
\S匹配非空白字符
数量词X?0或1次
X*0或多次
X+1或多次
X{n}恰好n次
X{n,}至少n次
X{n,m}n到m次
边界匹配^行首
$行尾
\b单词边界

2.2 正则表达式应用案例

测试
 public static void main(String[] args) {// 1、字符类(只能匹配单个字符)System.out.println("a".matches("[abc]"));    // [abc]只能匹配a、b、cSystem.out.println("e".matches("[abcd]")); // falseSystem.out.println("d".matches("[^abc]"));   // [^abc] 不能是abcSystem.out.println("a".matches("[^abc]"));  // falseSystem.out.println("b".matches("[a-zA-Z]")); // [a-zA-Z] 只能是a-z A-Z的字符System.out.println("2".matches("[a-zA-Z]")); // falseSystem.out.println("k".matches("[a-z&&[^bc]]")); // [a-z&&[^bc]] a到z,除了b和cSystem.out.println("b".matches("[a-z&&[^bc]]")); // falseSystem.out.println("ab".matches("[a-zA-Z0-9]")); // false 注意:以上带 [内容] 的规则都只能用于匹配单个字符// 2、预定义字符(只能匹配单个字符)  .  \d  \D   \s  \S  \w  \WSystem.out.println("徐".matches(".")); // .可以匹配任意字符System.out.println("徐徐".matches(".")); // false// \转义System.out.println("\"");// \n \tSystem.out.println("3".matches("\\d"));  // \d: 0-9System.out.println("a".matches("\\d"));  //falseSystem.out.println(" ".matches("\\s"));   // \s: 代表一个空白字符System.out.println("a".matches("\s")); // falseSystem.out.println("a".matches("\\S"));  // \S: 代表一个非空白字符System.out.println(" ".matches("\\S")); // falseSystem.out.println("a".matches("\\w"));  // \w: [a-zA-Z_0-9]System.out.println("_".matches("\\w")); // trueSystem.out.println("徐".matches("\\w")); // falseSystem.out.println("徐".matches("\\W"));  // [^\w]不能是a-zA-Z_0-9System.out.println("a".matches("\\W"));  // falseSystem.out.println("23232".matches("\\d")); // false 注意:以上预定义字符都只能匹配单个字符。// 3、数量词: ?   *   +   {n}   {n, }  {n, m}System.out.println("a".matches("\\w?"));   // ? 代表0次或1次System.out.println("".matches("\\w?"));    // trueSystem.out.println("abc".matches("\\w?")); // falseSystem.out.println("abc12".matches("\\w*"));   // * 代表0次或多次System.out.println("".matches("\\w*"));        // trueSystem.out.println("abc12张".matches("\\w*")); // falseSystem.out.println("abc12".matches("\\w+"));   // + 代表1次或多次System.out.println("".matches("\\w+"));       // falseSystem.out.println("abc12张".matches("\\w+")); // falseSystem.out.println("a3c".matches("\\w{3}"));   // {3} 代表要正好是n次System.out.println("abcd".matches("\\w{3}"));  // falseSystem.out.println("abcd".matches("\\w{3,}"));     // {3,} 代表是>=3次System.out.println("ab".matches("\\w{3,}"));     // falseSystem.out.println("abcde徐".matches("\\w{3,}"));     // falseSystem.out.println("abc232d".matches("\\w{3,9}"));     // {3, 9} 代表是  大于等于3次,小于等于9次// 4、其他几个常用的符号:(?i)忽略大小写 、 或:| 、  分组:()System.out.println("abc".matches("(?i)abc")); // trueSystem.out.println("ABC".matches("(?i)abc")); // trueSystem.out.println("aBc".matches("a((?i)b)c")); // trueSystem.out.println("ABc".matches("a((?i)b)c")); // false// 需求1:要求要么是3个小写字母,要么是3个数字。System.out.println("abc".matches("[a-z]{3}|\\d{3}")); // trueSystem.out.println("ABC".matches("[a-z]{3}|\\d{3}")); // falseSystem.out.println("123".matches("[a-z]{3}|\\d{3}")); // trueSystem.out.println("A12".matches("[a-z]{3}|\\d{3}")); // false// 需求2:必须是”我爱“开头,中间可以是至少一个”编程“,最后至少是1个”666“System.out.println("我爱编程编程666666".matches("我爱(编程)+(666)+"));System.out.println("我爱编程编程66666".matches("我爱(编程)+(666)+"));}
数据校验
// 手机号校验(支持手机和座机)
public static boolean validatePhone(String phone) {return phone.matches("(1[3-9]\\d{9})|(0\\d{2,7}-?[1-9]\\d{4,19})");//表示手机号 1开头,第二位是3-9,后面是9位的数字 //或 座机号:以0开头,后面区号长度2-7位,-?  -至多出现1次,开头1-9,后面4-19位的数字
}// 邮箱校验
public static boolean validateEmail(String email) {/*** dlei0009@163.com* 25143242@qq.com* itheima@itcast.com.cn*/return email.matches("\\w{2,}@\\w{2,20}(\\.\\w{2,10}){1,2}");// \\w 可能是英文字符或数字,{2,} 2位以上,有一个@,2-20位的字符或数字,//有一个.  \\. 第一个\ 告诉第二个\:你就是个\,第二个\告诉后面的.:你就是个.//\\w{2,10}  2-10位的字符或数字// (\\.\\w{2,10}){1,2} 表示(\\.\\w{2,10}) 这个表达式可能出现1-2次
}
信息爬取
// 从文本中提取所有电话号码
public static List<String> extractPhones(String text) {List<String> phones = new ArrayList<>();String regex = "(1[3-9]\\d{9})|(0\\d{2,7}-?[1-9]\\d{4,19})";Pattern pattern = Pattern.compile(regex);Matcher matcher = pattern.matcher(text);while (matcher.find()) {phones.add(matcher.group());}return phones;
}// 需求:从以下内容中爬取出,手机,邮箱,座机、400电话等信息。public static void method1(){String data = " 来学习Java,电话:1111111111,18699997777" +"        或者联系邮箱:boniufe@com.cn,\n" +"        热线电话:400-618-90960 40061897090";// 1、定义爬取规则//(1[3-9]\\d{9})|(0\\d{2,7}-?[1-9]\\d{4,19})  手机或座机的正则表达式//(\\w{2,}@\\w{2,20}(\\.\\w{2,10}){1,2}) 邮箱的表达式//(400-?\\d{3,7}-?\\d{3,7})  400开头,-可有可无,3-7位数字String regex = "(1[3-9]\\d{9})|(0\\d{2,7}-?[1-9]\\d{4,19})|(\\w{2,}@\\w{2,20}(\\.\\w{2,10}){1,2})"+ "|(400-?\\d{3,7}-?\\d{3,7})";// 2、把正则表达式封装成一个Pattern对象Pattern pattern = Pattern.compile(regex);// 3、通过pattern对象去获取查找内容的匹配器对象。Matcher matcher = pattern.matcher(data);// 4、定义一个循环开始爬取信息while (matcher.find()){String rs = matcher.group(); // 获取到了找到的内容了。System.out.println(rs);}}
文本处理

正则表达式用于搜索替换、分割内容,需要结合String提供的如下方法完成:

在这里插入图片描述

// 需求1:请把 古力娜扎ai8888迪丽热巴999aa5566马尔扎哈fbbfsfs42425卡尔扎巴,中间的非中文字符替换成 “-”String s1 = "古力娜扎ai8888迪丽热巴999aa5566马尔扎哈fbbfsfs42425卡尔扎巴";System.out.println(s1.replaceAll("\\w+", "-")); //数字或字符替换成-
// 需求2(拓展):某语音系统,收到一个口吃的人说的“我我我喜欢编编编编编编编编编编编编程程程!”,需要优化成“我喜欢编程!”。String s2 = "我我我喜欢编编编编编编编编编编编编程程程";/*** (.)一组:.匹配任意字符的。* \\1 :为这个组声明一个组号:1号* +:声明必须是重复的字* $1可以去取到第1组代表的那个重复的字*/System.out.println(s2.replaceAll("(.)\\1+", "$1")); // 替换所有非汉字字符
String result = text.replaceAll("[^\\u4e00-\\u9fa5]", "-");// 按数字分割字符串
String[] parts = text.split("\\d+");

2.3 高级技巧

  1. 非贪婪匹配:在量词后加?(如.*?)
  2. 分组引用:使用()分组,$n引用分组
  3. 前瞻后顾:(?=exp)正向前瞻,(?!exp)负向前瞻
// 提取用户名(非贪婪匹配)
public static List<String> extractUsernames(String text) {List<String> usernames = new ArrayList<>();Pattern pattern = Pattern.compile("欢迎(.+?)光临");Matcher matcher = pattern.matcher(text);while (matcher.find()) {usernames.add(matcher.group(1)); // 获取第一个分组}return usernames;
}

三、异常处理机制

3.1 异常体系结构

Java异常体系:
在这里插入图片描述

异常分类

  1. 编译时异常:必须显式处理(如IOException)
  2. 运行时异常:可处理也可不处理(如NullPointerException)

3.2 异常处理方式

在这里插入图片描述

抛出异常(throws)
public void readFile() throws IOException {// 可能抛出IOException的代码FileReader reader = new FileReader("file.txt");// ...
}

alt+回车 跑出异常

捕获异常(try-catch)

在这里插入图片描述

try {// 可能出错的代码int result = 10 / 0;
} catch (ArithmeticException e) {// 处理算术异常System.out.println("除数不能为零");e.printStackTrace();
} catch (Exception e) {// 处理其他异常System.out.println("发生未知错误");
} finally {// 无论是否异常都会执行System.out.println("清理资源");
}

3.3 自定义异常

在这里插入图片描述

自定义编译时异常

public class InvalidAgeException extends Exception {public InvalidAgeException() {super("年龄无效");}public InvalidAgeException(String message) {super(message);}
}

自定义运行时异常

public class BusinessException extends RuntimeException {public BusinessException(String message) {super(message);}
}

使用自定义异常

public void setAge(int age) throws InvalidAgeException {if (age < 0 || age > 150) {throw new InvalidAgeException("年龄必须在0-150之间");}this.age = age;
}

3.4 异常处理最佳实践

在这里插入图片描述
上图表示A调用B,B调用C,处理异常时,C抛出异常给B,B抛出异常给A,A是最上层,不能再抛, 需要处理,处理方法有两种:(1)记录异常反馈给用户,(2)尝试重新修复

  1. 优先处理具体异常:先捕获具体异常,再捕获通用异常
  2. 避免空catch块:至少记录异常信息
  3. 使用finally释放资源:确保资源正确关闭
  4. 异常信息清晰:提供足够的问题描述
  5. 合理使用自定义异常:封装业务相关异常
  6. 异常与返回码结合:根据场景选择合适方式
// 标准异常处理模板
public void processFile(String path) {FileInputStream fis = null;try {fis = new FileInputStream(path);// 处理文件} catch (FileNotFoundException e) {log.error("文件不存在: {}", path);throw new BusinessException("文件不存在");} catch (IOException e) {log.error("文件读取错误", e);throw new BusinessException("文件处理失败");} finally {if (fis != null) {try {fis.close();} catch (IOException e) {log.warn("关闭文件流失败", e);}}}
}

四、总结与应用场景

4.1 算法应用场景

  1. 冒泡/选择排序:小型数据集排序
  2. 二分查找:有序数据集快速查找
  3. 复杂算法:大型系统性能优化

4.2 正则表达式应用场景

  1. 表单验证:手机号、邮箱、身份证号等
  2. 日志分析:提取关键信息
  3. 文本处理:批量替换、格式转换
  4. 数据清洗:去除无效字符

4.3 异常处理应用场景

  1. 资源管理:文件、网络连接等
  2. 业务校验:参数检查、状态验证
  3. 系统边界:第三方服务调用
  4. 错误恢复:事务回滚、重试机制

综合最佳实践

  • 对用户输入使用正则验证
  • 核心业务逻辑使用自定义异常
  • 数据处理结合合适算法
  • 资源操作使用try-with-resources
// 综合应用示例:用户注册
public void registerUser(String username, String phone, String email) throws InvalidInputException {// 正则验证输入if (!validatePhone(phone)) {throw new InvalidInputException("手机号格式错误");}if (!validateEmail(email)) {throw new InvalidInputException("邮箱格式错误");}// 使用高效算法检查用户名是否已存在if (binarySearch(existingUsers, username) >= 0) {throw new BusinessException("用户名已存在");}// 保存用户(数据库操作)try {userDao.save(new User(username, phone, email));} catch (SQLException e) {throw new PersistenceException("用户保存失败", e);}
}

掌握这些核心技术,能够显著提升代码质量和开发效率。在实际项目中,合理组合使用算法、正则和异常处理,可以构建出健壮高效的Java应用程序。

http://www.dtcms.com/a/265902.html

相关文章:

  • 【机器学习深度学习】AI 项目开发流程:从需求到部署的五大阶段
  • Springboot3整合ehcache3缓存--XML配置和编程式配置
  • 移除 Java 列表中的所有空值
  • 一天两道力扣(1)
  • Linux多线程(十二)之【生产者消费者模型】
  • “Payload document size is larger than maximum of 16793600.“问题解决(MongoDB)
  • Kettle数据抽取(十一)作业-邮件
  • 什么是码率?剪映中如何选择适合的视频码率
  • C++(std::sort)
  • js-cookie详细介绍
  • Node.js与Webpack
  • 2025年6月:技术探索与生活平衡的协奏曲
  • 目标检测:从基础原理到前沿技术全面解析
  • 架构师的“降维打击”:用桥接模式,把 N*M 的问题变成 N+M
  • Matplotlib 安装使用教程
  • 【Git】同时在本地使用多个github账号进行github仓库管理
  • C++ 网络编程(14) asio多线程模型IOThreadPool
  • 【数据结构】树的基本操作
  • 阿里云服务网格ASM实践
  • 抗辐照芯片在核电厂火灾探测器中的应用优势与性能解析
  • springMvc的简单使用:要求在浏览器发起请求,由springMVC接受请求并响应,将个人简历信息展示到浏览器
  • Java 原生 HTTP Client
  • https如何利用工具ssl证书;使用自己生成的证书
  • http、SSL、TLS、https、证书
  • 【交互设计】UI 与 UX 简介:从核心概念到行业实践
  • 微算法科技(NASDAQ MLGO)基于量子图像处理的边缘检测算法:开拓图像分析新视野
  • [2025CVPR]SEEN-DA:基于语义熵引导的领域感知注意力机制
  • 通过观看数百个外科手术视频讲座来学习多模态表征|文献速递-最新论文分享
  • 【数据结构】哈希——闭散列/开散列模拟实现(C++)
  • [论文阅读] 人工智能 | 在非CUDA硬件上运行几何学习:基于Intel Gaudi-v2 HPU的PyTorch框架移植实践