文章目录
进阶:常见API(二)
一、常见算法
1.排序算法
1.1 冒泡排序
int[] arr = {5,2,3,4,6};
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
1.2 选择排序
int[] arr = {5,2,3,4,6};
for (int i = 0; i < arr.length - 1; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
2.查找算法
2.1 二分法查找(折半查找)算法
前提条件:数组中的数据必须是有序的
核心思想:每次排除一半的数据,查询数据的性能明显提高极多
int[] arr = {5, 2, 3, 1};
int ele = 5;
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (ele == arr[mid]) {
System.out.println("找到了,索引是:" + mid);
break;
} else if (ele > arr[mid]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
二、正则表达式
1.正则表达式概述
- 就是由一些特定的字符组成,代表的是一个规则
作用:用来校验数据格式是否合法
2.书写规则
- String提供了一个匹配正则表达式的方法
public boolean matches(String regex) 判断字符串是否匹配正则表达式,匹配返回true,不匹配返回false
2.1 字符类(只匹配单个字符)
符号 | 含义 |
---|---|
[] | 里面的内容出现一次 ([abc]:只能是a,b,或c; [a-zA-Z]:a到z,A到Z的字符) |
^ | 取反 ([^abc]:除了a,b,c之外的任何字符) |
&& | 交集,不能写单个的 & ([a-z&&[^m-p]]:a到z,除了m到p) |
[a-z[m-p]] | a-z,除了m-p |
2.2 预定义字符
符号 | 含义 |
---|---|
. | 任何字符(单独使用:\\.) |
\d | 一个数字:[0-9] \\d |
\D | 非数字:[^0-9] \\D |
\s | 一个空白字符 \\s |
\S | 非空白字符:[^\s] \\S |
\w | [a-zA-Z] \\w |
\W | 一个非单词字符:[^\w] \\W |
2.3 数量词
符号 | 含义 |
---|---|
? | 0次或1次 (a?:a字符出现0次或1次) |
* | 0次或多次 (a*:0次或多次a) |
+ | 1次或多次 (a+:1次或多次a) |
{} | 具体次数 ({3}:正好3次;{3,}:至少3次;{3,5}:至少3次但不超过5次) |
() | 表示分组,从左边开始第一个小括号是第一组 |
2.4 案例:判断QQ号是否符合规范
/**
* 体验正则表达式的好处
*/
public class Demo {
public static void main(String[] args) {
String qq = "8a888888";
boolean flag = checkQQ2(qq);
System.out.println(flag);
}
public static boolean checkQQ2(String qq) {
return qq != null && qq.matches("[1-9]\\d{5,10}");
}
/*
不能以0开头
每个字符都是数字字符
位数 6-11
*/
public static boolean checkQQ(String qq) {
if(qq == null) {
return false;
}
//位数 6-11
if(qq.length() < 6 || qq.length() > 11) {
return false;
}
//不能以0开头
if(qq.startsWith("0")) {
return false;
}
//每个字符都是数字字符
for(int i = 0; i < qq.length(); i++) {
//char ch = qq.charAt(i)
char ch = qq.charAt(i);
//判断ch是否是数字字符
if(ch < '0' || ch > '9') {
return false;
}
}
return true;
}
}
3.用于查找信息的API(Matcher)
package d5_regexCom;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexFindDemo {
public static void main(String[] args) {
String data = " 来黑马程序员学习Java,\n" +
" 电话:1866668888,18699997777\n" +
" 或者联系邮箱:boniu@itcast.cn,\n" +
" 座机电话:01036517895,010-98951256\n" +
" 邮箱:bozai@itcast.cn,\n" +
" 邮箱:dlei0009@163.com,\n" +
" 热线电话:400-618-9090 ,400-618-4000,4006184000,4006189090";
//String regex = "1[345789]\\d{9}\\w{4,20}@[a-zA-Z0-9]{2,7}\\.\\w{2,3}|400-?\\d{3}-?\\d{4}"; //热线格式
String regex = "1[345789]\\d{9}|"+
"\\w{4,20}@[a-zA-Z0-9]{2,7}\\.\\w{2,3}|"+
"400-?\\d{3}-?\\d{4}|010-?\\d{8,10}";
//把正则表达式 封装 为一个 Pattern对象
Pattern pattern = Pattern.compile(regex);
//通过 Pattern对象得到查找内容的 匹配器
Matcher matcher = pattern.matcher(data);
//匹配器 查找信息
while (matcher.find()) {
//得到查找到的 字符串
String group = matcher.group();
System.out.println(group);
}
String data1 = "欢迎张全蛋光临本系统!他删库并跑路\n" +
"欢迎李二狗子光临本系统!\n" +
"欢迎马六子光临本系统!它浏览了很多好看的照片!\n" +
"欢迎夏洛光临本系统!他在六点钟送出了一个嘉年华\n";
String regex1 = "欢迎(.+?)光临";
//把正则表达式 封装 为一个 Pattern对象
Pattern pattern1 = Pattern.compile(regex1);
//通过 Pattern对象得到查找内容的 匹配器
Matcher matcher1= pattern1.matcher(data1);
//匹配器 查找信息
while (matcher1.find()) {
//得到查找到的 字符串
String group = matcher1.group(1);//获取到 第一组的内容
System.out.println(group);
}
}
}
4.用于搜索替换、分割内容
- 正则表达式用于搜索替换、分割内容**,需要结合String提供的如下方法完成:**
方法名 | 说明 |
---|---|
public String replaceAll(String regex, String newStr) | 按照正则表达式匹配的内容进行替换 |
public String[] split(String regex) | 按照正则表达式的内容进行分割字符串,返回一个String数组 |
import java.util.Arrays;
public class MatchDemo {
public static void main(String[] args) {
String str = "我是中国人,我很骄傲!!!";
System.out.println(str.replaceAll("!+", "。"));
String str1 = "张123李234死死34566546呜呜2342溜溜。";
String[] split = str1.split("\\d+");
System.out.println(Arrays.toString(split));
}
}
三、异常
- 是代码在编译或者**执行(RuntimeException)**的过程中可能出现的错误
1.异常的体系
1.1 Error:
代表的是系统级别错误(属于严重问题),也就是说系统一旦出现问题,Sun公司会把这些问题封装成Error对象给出来,说白了,Error是个Sun公司自己用的,不是给我们程序员用的,因此开发人员不用管它
1.2 Exception
异常,它代表的才是我们程序可能出现的问题,所以,我们程序员通常会用Exception以及它的孩子来封装程序出现的问题
2.异常的种类
2.1 运行时异常
RuntimeException及其子类,编译阶段不会出现错误提醒,运行时出现的异常
2.2 编译时异常
编译阶段就会出现错误提醒的
2.3 自定义异常
Java无法为这个世界上全部的问题都提供异常类来代表, 如果企业自己的某种问题,想通过异常来表示,以便用异常来管理该问题,那就需要自己来定义异常类了
-
自定义异常的种类:
自定义运行时异常:
- 定义一个异常类继承RuntimeException
- 重写构造器
- 通过throw new 异常类(xxx)来创建异常对象并抛出
编译阶段不会报错,提醒不强烈,运行时才可能出现!
自定义编译时异常:
- 定义一个异常类继承Exception
- 重写构造器
- 通过throw new 异常类(xxx)来创建异常对象并抛出
编译阶段就报错,提醒更加强烈!
3.异常的处理
3.1 抛出异常(throws)
在方法上使用throws关键字,可以将方法内部出现的异常跑出去给调用者处理
方法 throws 异常1,异常2,异常3...{ ... }
3.2 捕获异常(try…catch)
直接捕获程序出现的异常
try{ //监视可能出现异常的代码! }catch(异常类型1 变量){ //处理异常 }catch(异常类型2 变量){ //处理异常 }...
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExceptionDemo {
//1. throws ParseException: 抛出异常
public static void main(String[] args) /*throws ParseException*/ {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// 2. try - catch 捕获异常
try{
Date d = sdf.parse("2023/12/18");
System.out.println(d);
}catch (ParseException e){ // Exception e
System.err.println("代码出现了异常!");
}
}
}
4.异常的作用
- 异常是用来查询系统Bug的关键参考信息!
- 异常可以作为方法内部的一种特殊返回值,以便通知上层盗用者底层的执行情况!
5.throw和throws的区别
throw
代表动作,表示抛出一个异常的动作;
用在方法实现中,抛出一个制造的异常。
throws
代表一种状态,代表方法可能有异常抛出;
用在方法声明中,可以抛出多个异常。