目录
需求1:从以下内容中爬取出,手机,邮箱,座机、400电话等信息。
需求3:某系统的日志文件记录了当天进入系统的全部用户信息,需要把这些用户的名字爬取出来另作他用。
arrays.sort(数组):对数组进行排序
算法:解决某个实际问题的过程和方法
排序算法:(冒泡排序,选择排序)
冒泡排序
每次从数组中找出最大值放在数组的后面去
public class Test1 {
public static void main(String[] args) {
//1.准备一个数组
int[] arr ={5,2,3,1};
//2.定义一个循环控制排几轮
for (int i = 0; i < arr.length-1; i++) {
//i = 0 1 2 【5,2,3,1】 次数
//i =0 第一轮 0,1,2 3
//i =1 第二轮 0,1, 2
//i =2 第三轮 0 1
// 3.定义一个循环控制每轮比较几次
for (int j = 0; j < arr.length-i-1; j++) {
//判断当前位置的元素值,是否大于后一个位置处的元素值,如果大则交换
if(arr[j]>arr[j+1]){
int temp =arr[j+1];
arr[j+1] =arr[j];
arr[j] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
}
选择排序
每轮选择当前位置,开始找出后面的较小值与该位置交换
public class Test {
public static void main(String[] args) {
//1.准备一个数组
int[] arr ={5,1,3,2};//2.选择控制几轮
for (int i = 0; i < arr.length-1; i++) {
//i =0 第一轮 J=1 2 3
//i =1 第二轮 J=2 3
//i =2 第三轮 J =3 1
// 3.控制每轮选择几次
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;
}
}
}
System.out.println(Arrays.toString(arr));
}
}
查找算法:二分(折半查找)
前提条件:数组中的数据必须是有序的
核心思想:每次排除一半的数据,查询数据的性能明显提高极多!
二分查找的实现步骤是什么样的 ?
定义变量记录左边和右边位置。
使用 while 循环控制二分查询(条件是左边位置 <= 右边位置)
循环内部获取中间元素索引
判断当前要找的元素如果大于中间元素,左边位置 = 中间索引 +1
判断当前要找的元素如果小于中间元素,右边位置 = 中间索引 -1
判断当前要找的元素如果等于中间元素,返回当前中间元素索引。
public class Test3 {
public static void main(String[] args) {
//1.准备一个数据
int[] arr ={7,23,79,81,103,177,178,201};System.out.println(binarySearch(arr,150));
System.out.println(Arrays.binarySearch(arr,81));
}
public static int binarySearch(int[] arr,int data){
//1.定义两个变量,一个站在左边位置,一个右边位置
int left = 0;
int right = arr.length-1;
//2.定义一个循环控制折半
while (left <=right) {
//3.每次折半,都算出中间位置处的索引
int middle = (left + right) / 2;
//4.判断当前要找的元素值,与中间位置处的元素值的大小情况
if (data < arr[middle]) {
//往左边找,截至位置(右边位置)= 中间位置 -1
right = middle - 1;
} else if (data > arr[middle]) {
//往右边找,截至位置(左边位置)= 中间位置 +1
left = middle + 1;
} else {
//中间位置处的元素值,正好等于我们要找的元素值
return middle;
}
}
return -1;//-1特殊结果,就表示没有找到数据!数组中不存在该数据!
}
}
正则表达式
由一些特定的字符组成,代表的是一个原则。
作用一:用来校验数据格式是否合法
作用二: 在一段文本中查找满足要求的内容
qq.matches() 让字符串对象与送进来的正则表达式进行匹配,成功true,失败false
package com.itheima.d2_regex;
/**
* 目标:体验一下使用正则表达式来校验数据格式的合法性。
* 需求:校验QQ号码是否正确,要求全部是数字,长度是(6-20)之间,不能以0开头。
*/
public class RegexTest1 {
public static void main(String[] args) {
System.out.println(checkQQ(null));
System.out.println(checkQQ("251425876"));
System.out.println(checkQQ("2514a8d76"));
System.out.println("--------------------------------------------------");System.out.println(checkQQ1(null));
System.out.println(checkQQ1("251425876"));
System.out.println(checkQQ1("2514a8d76"));}
public static boolean checkQQ1(String qq){
return qq != null && qq.matches("[1-9]\\d{5,19}"); // \\d剩下的数字共6到20位
}public static boolean checkQQ(String qq){
// 1、判断qq号码是否为null
if(qq == null || qq.startsWith("0") || qq.length() < 6 || qq.length() > 20){
return false;
}// 2、qq至少是不是null,不是以0开头的,满足6-20之间的长度。
// 判断qq号码中是否都是数字。
// qq = 2514ghd234
for (int i = 0; i < qq.length(); i++) {
// 根据索引提取当前位置处的字符。
char ch = qq.charAt(i);
// 判断ch记住的字符,如果不是数字,qq号码不合法。
if(ch < '0' || ch > '9'){
return false;
}
}
// 3、说明qq号码肯定是合法
return true;
}
}
package com.itheima.d2_regex;
/**
* 目标:掌握正则表达式的书写规则
*/
public class RegexTest2 {
public static void main(String[] args) {
// 1、字符类(只能匹配单个字符)
System.out.println("a".matches("[abc]")); // [abc]只能匹配a、b、c
System.out.println("e".matches("[abcd]")); // falseSystem.out.println("d".matches("[^abc]")); // [^abc] 不能是abc
System.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,除了b和c
System.out.println("b".matches("[a-z&&[^bc]]")); // falseSystem.out.println("ab".matches("[a-zA-Z0-9]")); // false 注意:以上带 [内容] 的规则都只能用于匹配单个字符
// 2、预定义字符(只能匹配单个字符) . \d \D \s \S \w \W
//在java中,\是有特殊用途的,例如特殊字符 \n 换行 \t缩进
System.out.println("徐".matches(".")); // .可以匹配任意字符
System.out.println("徐徐".matches(".")); // false// \转义
System.out.println("\"");
// \n \t
System.out.println("3".matches("\\d")); // \d: 0-9
System.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")); // true
System.out.println("徐".matches("\\w")); // falseSystem.out.println("徐".matches("\\W")); // [^\w]不能是a-zA-Z_0-9
System.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?")); // true
System.out.println("abc".matches("\\w?")); // falseSystem.out.println("abc12".matches("\\w*")); // * 代表0次或多次
System.out.println("".matches("\\w*")); // true
System.out.println("abc12张".matches("\\w*")); // falseSystem.out.println("abc12".matches("\\w+")); // + 代表1次或多次
System.out.println("".matches("\\w+")); // false
System.out.println("abc12张".matches("\\w+")); // falseSystem.out.println("a3c".matches("\\w{3}")); // {3} 代表要正好是n次
System.out.println("abcd".matches("\\w{3}")); // false
System.out.println("abcd".matches("\\w{3,}")); // {3,} 代表是>=3次
System.out.println("ab".matches("\\w{3,}")); // false
System.out.println("abcde徐".matches("\\w{3,}")); // false
System.out.println("abc232d".matches("\\w{3,9}")); // {3, 9} 代表是 大于等于3次,小于等于9次// 4、其他几个常用的符号:(?i)忽略大小写 、 或:| 、 分组:()
System.out.println("abc".matches("(?i)abc")); // true
System.out.println("ABC".matches("(?i)abc")); // true
System.out.println("aBc".matches("a((?i)b)c")); // true
System.out.println("ABc".matches("a((?i)b)c")); // false// 需求1:要求要么是3个小写字母,要么是3个数字。
System.out.println("abc".matches("[a-z]{3}|\\d{3}")); // true
System.out.println("ABC".matches("[a-z]{3}|\\d{3}")); // false
System.out.println("123".matches("[a-z]{3}|\\d{3}")); // true
System.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 class RegexTest3 {
public static void main(String[] args) {
// checkPhone();
checkEmail();
}public static void checkPhone(){
while (true) {
System.out.println("请您输入您的电话号码(手机|座机): ");
Scanner sc = new Scanner(System.in);
String phone = sc.nextLine();
// 18676769999 010-3424242424 0104644535
if(phone.matches("(1[3-9]\\d{9})|(0\\d{2,7}-?[1-9]\\d{4,19})")){
System.out.println("您输入的号码格式正确~~~");
break;
}else {
System.out.println("您输入的号码格式不正确~~~");
}
}
}public static void checkEmail(){
while (true) {
System.out.println("请您输入您的邮箱: ");
Scanner sc = new Scanner(System.in);
String email = sc.nextLine();
/**
* dlei0009@163.com
* 25143242@qq.com
* itheima@itcast.com.cn
*/
if(email.matches("\\w{2,}@\\w{2,20}(\\.\\w{2,10}){1,2}")){ //@之前两位以上
System.out.println("您输入的邮箱格式正确~~~");
break;
}else {
System.out.println("您输入的邮箱格式不正确~~~");
}
}
}
}
用于查找信息 :
需求1:从以下内容中爬取出,手机,邮箱,座机、400电话等信息。
/**
* 目标:掌握使用正则表达式查找内容。
*/
public class RegexTest4 {
public static void main(String[] args) {
method1();
}// 需求1:从以下内容中爬取出,手机,邮箱,座机、400电话等信息。
public static void method1(){
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";
// 1、定义爬取规则
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);
}
}
需求2:把全部邮箱的账户名找出来。
需求3:某系统的日志文件记录了当天进入系统的全部用户信息,需要把这些用户的名字爬取出来另作他用。
public class RegexTest5 {
public static void main(String[] args) {
method2();
}// 需求2:把全部邮箱的账户名找出来。
public static void method1(){
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 ,heima, 400-618-4000,4006184000,4006189090";
// 1、定义爬取规则
String regex = "(\\w{2,})@(\\w{2,20})(\\.\\w{2,10}){1,2}";
// 2、把正则表达式封装成一个Pattern对象
Pattern pattern = Pattern.compile(regex);
// 3、通过pattern对象去获取查找内容的匹配器对象。
Matcher matcher = pattern.matcher(data);
// 4、定义一个循环开始爬取信息
while (matcher.find()){
System.out.println(matcher.group());
System.out.println(matcher.group(1)); // 指定获取正则表达式匹配后的第一组内容
System.out.println(matcher.group(2)); // 指定获取正则表达式匹配后的第二组内容
}
}
// 需求3:某系统的日志文件记录了当天进入系统的全部用户信息,需要把这些用户的名字爬取出来另作他用。
public static void method2(){
String data = "欢迎张全蛋光临本系统!他删库并跑路,欢迎李二狗子光临本系统!" +
"欢迎马六子光临本系统!它浏览了很多好看的照片!欢迎夏洛光临本系统!他在六点钟购买了一台拖拉机!";
// 1、定义爬取规则
// String regex = "欢迎(.+)光临"; // 贪婪匹配
String regex = "欢迎(.+?)光临"; // +? 非贪婪匹配
// 2、把正则表达式封装成一个Pattern对象
Pattern pattern = Pattern.compile(regex);
// 3、通过pattern对象去获取查找内容的匹配器对象。
Matcher matcher = pattern.matcher(data);
// 4、定义一个循环开始爬取信息
while (matcher.find()){
System.out.println(matcher.group());
System.out.println(matcher.group(1));
}
}
}
用于搜索替换、分割功能
public class RegexTest6 {
public static void main(String[] args) {
// 1、public String replaceAll(String regex , String newStr):按照正则表达式匹配的内容进行替换
// 需求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"));// 2、public String[] split(String regex):按照正则表达式匹配的内容进行分割字符串,返回一个字符串数组。
// 需求1:请把 古力娜扎ai8888迪丽热巴999aa5566马尔扎哈fbbfsfs42425卡尔扎巴,中的人名获取出来。
String s3 = "古力娜扎ai8888迪丽热巴999aa5566马尔扎哈fbbfsfs42425卡尔扎巴";
String[] names = s3.split("\\w+");
System.out.println(Arrays.toString(names));
}
}
异常
代表程序出现的问题
Exception :叫异常,它代表的才是我们程序可能出现的问题,所以,我们程序员通常会Exception 以及它的孩子来封装程序出现的问题。
运行时异常: RuntimeException 及其子类,编译阶段不会出现错误提醒,运行时出现的异常(如:数组索引越界异常)
编译时异常:编译阶段就会出现错误提醒的。(如:日期解析异常)
1.抛出异常( throws parseException)
在方法上使用 throws 关键字,可以将方法内部出现的异常抛出去给调用者处理。2.捕获异常 (try...catch) //try监视异常,catch捕获异常
直接捕获程序出现的异常。
自定义异常
Java 无法为这个世界上全部的问题都提供异常类来代表, 如果企业自己的某种问题,想通过异常来表示,以便用异常来管理该问题,那就需要自己来定义异常类了。
异常作用:1. 异常是用来查寻系统Bug的关键参考信息
2.异常可以作为方法内部的一种特殊返回值,以便通知上层调用者底层的执行情况!
// 1、必须让这个类继承自Exception,才能成为一个编译时异常类。 public class AgeIllegalException extends Exception{ public AgeIllegalException() { } public AgeIllegalException(String message) { super(message); } }
// 1、必须让这个类继承自RuntimeException,才能成为一个运行时异常类。 public class AgeIllegalRuntimeException extends RuntimeException{ public AgeIllegalRuntimeException() { } public AgeIllegalRuntimeException(String message) { super(message); } }
public class ExceptionTest2 { public static void main(String[] args) { // 需求:保存一个合法的年龄 // try { // saveAge(223); // System.out.println("底层执行成功的!"); // } catch (Exception e) { // e.printStackTrace(); // System.out.println("底层出现了bug!"); // } try { saveAge2(225); System.out.println("saveAge2底层执行是成功的!"); } catch (AgeIllegalException e) { e.printStackTrace(); System.out.println("saveAge2底层执行是出现bug的!"); } } public static void saveAge2(int age) throws AgeIllegalException{ if(age > 0 && age < 150){ System.out.println("年龄被成功保存: " + age); }else { // 用一个异常对象封装这个问题 // throw 抛出去这个异常对象 // throws 用在方法上,抛出方法内部的异常 throw new AgeIllegalException("/age is illegal, your age is " + age); } } public static void saveAge(int age){ if(age > 0 && age < 150){ System.out.println("年龄被成功保存: " + age); }else { // 用一个异常对象封装这个问题 // throw 抛出去这个异常对象 throw new AgeIllegalRuntimeException("/age is illegal, your age is " + age); } } }
异常的处理
1.捕获异常,记录异常并响应合适信息给用户
2.捕获异常,尝试重新修复
public class ExceptionTest3 {
public static void main(String[] args) {
try {
test1();
} catch (FileNotFoundException e) {
System.out.println("您要找的文件不存在!!");
e.printStackTrace(); // 打印出这个异常对象的信息。记录下来。
} catch (ParseException e) {
System.out.println("您要解析的时间有问题了!");
e.printStackTrace(); // 打印出这个异常对象的信息。记录下来。
}
}
public static void test1() throws FileNotFoundException, ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse("2028-11-11 10:24:11");
System.out.println(d);
test2();
}
public static void test2() throws FileNotFoundException {
// 读取文件的。
InputStream is = new FileInputStream("D:/meinv.png");
}
}
public class ExceptionTest3_2 {
public static void main(String[] args) {
try {
test1();
} catch (Exception e) {
System.out.println("您当前操作有问题");
e.printStackTrace(); // 打印出这个异常对象的信息。记录下来。
}
}
public static void test1() throws Exception {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse("2028-11-11 10:24:11");
System.out.println(d);
test2();
}
public static void test2() throws Exception {
// 读取文件的。
InputStream is = new FileInputStream("D:/meinv.png");
}
}
public class ExceptionTest4 {
public static void main(String[] args) {
// 需求:调用一个方法,让用户输入一个合适的价格返回为止。
// 尝试修复
while (true) {
try {
System.out.println(getMoney());
break;
} catch (Exception e) {
System.out.println("请您输入合法的数字!!");
}
}
}
public static double getMoney(){
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请您输入合适的价格:");
double money = sc.nextDouble();
if(money >= 0){
return money;
}else {
System.out.println("您输入的价格是不合适的!");
}
}
}
}