以下学习笔记记录于:2024.09.18-2024.09.24
文章目录
阶段二 JavaSE进阶
第三章 JDK8新特性、算法、正则表达式、异常
3-3 正则表达式
75 概述
- 正则表达式作用一:用来校验数据格式是否合法
RegexTest1.java:
package com.itheima.hello.d2_regex;
/*
* 目标:体验一下使用正则表达式来校验数据格式的合法性
* 需求:校验QQ号码是否正确,要求全部是数字、长度在(6-20)之间、不能以0开头
* */
public class RegexTest1 {
public static void main(String[] args) {
System.out.println(checkQQ(null));
System.out.println(checkQQ("13294862"));
System.out.println(checkQQ("1329a862"));
System.out.println("--------------");
System.out.println(checkQQ(null));
System.out.println(checkQQ("13294862"));
System.out.println(checkQQ("1329a862"));
}
// 运用正则表达式更加简便
public static boolean checkQQ1(String qq){
return qq != null && qq.matches("[1,9]\\d{5,19}");
}
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号码中是否都是数字
for (int i = 0; i < qq.length(); i++) {
char q = qq.charAt(i);
if (q < '0' || q > '9'){
return false;
}
}
return true;
}
}
运行结果:
76 书写规则
RegexTest2.java:
package com.itheima.hello.d2_regex;
public class RegexTest2 {
public static void main(String[] args) {
// 1、字符类(只能匹配单个字符)
// [abc] 只能匹配a、b、c
System.out.println("a".matches("[abc]")); // true
System.out.println("e".matches("[abc]")); // false
// [^abc] 不能是a、b、c
System.out.println("d".matches("[^abc]")); // true
System.out.println("a".matches("[^abc]")); // false
// [a-zA-Z] 只能是a-z、A-Z的字符
System.out.println("z".matches("[a-zA-Z]")); // true
System.out.println("1".matches("[a-zA-Z]")); // false
// [a-z&&[^bc]] 在a-z,但除了b、c
System.out.println("k".matches("[a-z&&[^bc]]")); // true
System.out.println("b".matches("[a-z&&[^bc]]")); // false
// [a-zA-Z0-9] 在a-z、A-Z、0-9的字符
System.out.println("ab".matches("[a-zA-Z0-9]")); // false(只能匹配单个字符)
// 2、预定义字符(只能匹配单个字符) . \d \D \s \S \w \W
// . 可以匹配任意字符
System.out.println("徐".matches(".")); // true
System.out.println("徐徐".matches(".")); // false
// \d 为0-9
System.out.println("3".matches("\\d")); // true
System.out.println("a".matches("\\d")); // false
System.out.println("123".matches("\\d")); // false
// \s 代表一个空白字符
System.out.println(" ".matches("\s")); // true
System.out.println("a".matches("\s")); // false
// \S 代表一个非空白字符
System.out.println("a".matches("\\S")); // true
System.out.println(" ".matches("\\S")); // false
// \w为[a-zA-Z_0-9]
System.out.println("a".matches("\\w")); // true
System.out.println("_".matches("\\w")); // true
System.out.println("徐".matches("\\w")); // false
// \W表示不能是[a-zA-Z_0-9]
System.out.println("徐".matches("\\W")); // true
System.out.println("a".matches("\\W")); // false
// 3、数量词(可支持匹配单个或多个字符):? * + {n} {n,} {n,m}
// ? 代表0次或1次
System.out.println("a".matches("\\w?")); // true
System.out.println("".matches("\\w?")); // true
System.out.println("abc".matches("\\w?")); // false
// * 表示0次或多次
System.out.println("ab12".matches("\\w*")); // true
System.out.println("".matches("\\w*")); // true
System.out.println("abc徐".matches("\\w*")); // false
// + 表示1次或多次
System.out.println("ab12".matches("\\w+")); // true
System.out.println("".matches("\\w+")); // false
System.out.println("abc徐".matches("\\w+")); // false
// {n} 代表正好是出现n次
System.out.println("ab1".matches("\\w{3}")); // true
System.out.println("abc1".matches("\\w{3}")); // false
// {n,} 代表 >=n 次
System.out.println("abc".matches("\\w{3,}")); // true
System.out.println("ab".matches("\\w{3,}")); // false
// {n,m} 代表 >=n, <=m 次
System.out.println("abce".matches("\\w{3,5}")); // true
System.out.println("ab".matches("\\w{3,5}")); // false
System.out.println("abcdef".matches("\\w{3,5}")); // false
System.out.println("-----------------");
// 4、其他几个常用的符号 (?i)忽略大小写 |或 ()分组
System.out.println("abc".matches("(?i)abc")); // true
System.out.println("aBc".matches("(?i)abc")); // true
System.out.println("aBc".matches("((?i)a)bc")); // false
System.out.println("Abc".matches("((?i)a)bc")); // true
// 需求1:要求要么是3个小写字母,要么是3个数字
System.out.println("123".matches("[a-z]{3}|\\d{3}")); // true
System.out.println("and".matches("[a-z]{3}|\\d{3}")); // true
System.out.println("aNd".matches("[a-z]{3}|\\d{3}")); // false
// 需求2:必须是“我爱”开头,中间可以是至少一个“编程”,最后至少是1个“666”
System.out.println("我爱编程编程666".matches("我爱(编程)+(666)+")); // true
System.out.println("编程编程666".matches("我爱(编程)+(666)+")); // false
System.out.println("我爱666".matches("我爱(编程)+(666)+")); // false
System.out.println("我爱编程6666".matches("我爱(编程)+(666)+")); // false
}
}
77 应用案例
RegexTest3.java:
package com.itheima.hello.d2_regex;
import java.util.Scanner;
/*
* 运用正则表达式完成需求:校验用户输入的电话、邮箱是否合法
* */
public class RegexTest3 {
public static void main(String[] args) {
checkPhone();
checkEmail();
}
private static void checkPhone() {
while (true) {
System.out.println("请输入您的电话号码(手机或座机):");
Scanner sc = new Scanner(System.in);
String phone = sc.nextLine(); // 获取用户输入的一行数据
// 手机:17263354976 座机:010-1243423578 127346819
// 手机:1[3-9]\\d{9} 首位数字为1,第二位在3-9之间(包含3,9),再加9位数字(手机号码一共为11位)
// 座机:0\\d{2,7}-?[1-9]\\d{4,19} 首位数字为0,加上2-7位的数字(包含首位数字0,此处一共有3-8位作为区号),-符号允许出现0次或1次,-符号后紧接着的第一个数字为1-9之间的数字,后面再加4-19位数字(-符号后一共为5-20位数字)
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("您输入的电话号码格式不正确,请重新输入~~");
}
}
}
private static void checkEmail() {
while (true) {
System.out.println("请输入您的邮箱:");
Scanner sc = new Scanner(System.in);
String email = sc.nextLine(); // 获取用户输入的一行数据
/*
* 假设正确邮箱格式有如下3种:
* 237859156ah@qq.com
* 237859156ah@163.com
* 237859156ah@itheima.com.cn
*
* 分为三部分:@前,@,@后
* @前:\\w{2,} 表示[a-zA-Z_0-9]出现>=2次
* @后:\\w{2,20}(\\.\\w{2,10}){1,2} ——> \\w{2,20} 表示[a-zA-Z_0-9]出现>=2,<=20次
* \\.\\w{2,10} 表示首字符为“.”,之后紧接2-10个[a-zA-Z_0-9]范围内的字符
* (\\.\\w{2,10}){1,2} 表示\\.\\w{2,10}出现>=1,<=2次
* */
if (email.matches("\\w{2,}@\\w{2,20}(\\.\\w{2,10}){1,2}")){
System.out.println("您输入的邮箱格式正确!!!");
break;
}else {
System.out.println("您输入的邮箱格式不正确,请重新输入~~");
}
}
}
}
78 爬取信息
- 正则表达式作用二:在一段文本中查找满足要求的内容
RegexTest4.java:
package com.itheima.hello.d2_regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
* 目标:掌握使用正则表达式查找内容
*/
public class RegexTest4 {
public static void main(String[] args) {
method1();
}
// 需求1:从以下内容中爬取出手机、邮箱、座机、400电话等信息
private 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);
}
}
}
运行结果:
79 用于搜索、替换内容
RegexTest6.java:
package com.itheima.hello.d2_regex;
import java.lang.ref.SoftReference;
import java.util.Arrays;
/*
* 目标:掌握使用正则表达式做搜索替换、内容分割
*/
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));
}
}
运行结果:
3-4 异常
80 认识异常
- 异常就是代表程序出现的问题
关于异常的处理方式:抛出异常、捕获异常
81 自定义异常
AgeIllegalRuntimeException.java:
package com.itheima.hello.d3_exception;
// 1、必须让这个类继承自RuntimeException(运行时异常)
public class AgeIllegalRuntimeException extends RuntimeException{
public AgeIllegalRuntimeException() {
}
public AgeIllegalRuntimeException(String message) {
super(message);
}
}
AgeIllegalException.java:
package com.itheima.hello.d3_exception;
// 2、必须让这个类继承自Exception(编译时异常)
public class AgeIllegalException extends Exception{
public AgeIllegalException() {
}
public AgeIllegalException(String message) {
super(message);
}
}
ExceptionTest2.java:
package com.itheima.hello.d3_exception;
// 需求:保存一个合法的年龄
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(223);
System.out.println("saveAge2底层执行成功!");
} catch (AgeIllegalException e) {
e.printStackTrace();
System.out.println("saveAge2底层执行出现bug");
}
}
private 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);
}
}
private 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);
}
}
}
运行结果:
82 异常的两种处理方式(方式一)
- 方式一:捕获异常,记录异常并响应合适的信息给用户
ExceptionTest3.java:
package com.itheima.hello.d3_exception;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
// 目标:异常的处理
public class ExceptionTest3 {
public static void main(String[] args) {
try {
test1();
} catch (ParseException e) {
System.out.println("您要解析的时间有问题");
e.printStackTrace(); // 打印出这个异常对象的信息,记录下来
} catch (FileNotFoundException e) {
System.out.println("您要找的文件不存在");
e.printStackTrace(); // 打印出这个异常对象的信息,记录下来
}
}
private static void test1() throws ParseException, FileNotFoundException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse("2028-11-11 10:24:22"); // 缺了秒数
System.out.println(d);
test2();
}
// 读取文件
private static void test2() throws FileNotFoundException {
InputStream is = new FileInputStream("D:/z.png");
}
}
ExceptionTest3_2.java:(代码优化)
package com.itheima.hello.d3_exception;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
// 目标:异常的处理(代码优化)
public class ExceptionTest3_2 {
public static void main(String[] args) {
try {
test1();
} catch (Exception e) {
System.out.println("您当前的操作存在问题");
e.printStackTrace(); // 打印出这个异常对象的信息,记录下来
}
}
private static void test1() throws Exception {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = sdf.parse("2028-11-11 10:24"); // 缺了秒数
System.out.println(d);
test2();
}
// 读取文件
private static void test2() throws Exception {
InputStream is = new FileInputStream("D:/z.png");
}
}
运行结果:
83 异常的两种处理方式(方式二)
- 方式二:捕获异常,尝试重新修复
ExceptionTest4.java:
package com.itheima.hello.d3_exception;
import java.util.Scanner;
// 需求:调用一个方法,让用户输入一个合适的价格返回为止
public class ExceptionTest4 {
public static void main(String[] args) {
while (true) {
try {
System.out.println(getMoney());
break;
} catch (Exception e) {
System.out.println("请您输入合法的数字!!!");
}
}
}
private 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("您输入的价格有误,请重新输入");
}
}
}
}
运行结果:
第四章 集合框架
4-1 Collection集合
84 集合进阶概述
CollectionTest1.java:
package com.itheima.hello.d1_collection;
import java.util.ArrayList;
import java.util.HashSet;
// 目标:认识Collection体系的特点
public class CollectionTest1 {
public static void main(String[] args) {
// 简单确认一下Collection集合的特点
ArrayList<String> list = new ArrayList<>(); // 有序、可重复、有索引
list.add("java1");
list.add("java2");
list.add("java1");
list.add("java2");
list.add("java3");
System.out.println(list);
HashSet<String> set = new HashSet<>(); // 无序、不重复、无索引
set.add("java1");
set.add("java2");
set.add("java1");
set.add("java2");
set.add("java3");
System.out.println(set);
}
}
运行结果:
85 Collection集合的常用方法(API)
- public boolean addAll(Collection<? extends E> c):把一个集合的全部数据倒入到另一个集合中去
CollectionTest2API.java:
package com.itheima.hello.d1_collection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class CollectionTest2API {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>(); // 多态写法
// 1.public boolean add(E e):添加元素,添加成功返回true。
c.add("java1");
c.add("java2");
c.add("java1");
c.add("java2");
System.out.println("c数组内容有:" + c);
// 2.public void clear():清空集合的元素。
// c.clear();
// System.out.println(c);
// 3.public boolean isEmpty():判断集合是否为空,是空返回true,反之false。
System.out.println(c.isEmpty());
// 4.public int size():获取集合的大小。
System.out.println(c.size());
// 5.public boolean contains(Object obj):判断集合中是否包含某个元素。
System.out.println(c.contains("java1"));
System.out.println(c.contains("java3"));
// 6.public boolean remove(E e):删除某个元素:如果有多个重复元素默认删除前面的第一个!
c.remove("java1");
System.out.println("c数组内容有:" + c);
// 7.public Object[] toArray():把集合转换成数组
Object[] a = c.toArray();
System.out.println("a数组内容有:" + Arrays.toString(a));
// 若非要转为String类型的数组,则需要保证c中的内容全为String类型的数据,否则会出错。
String[] b = c.toArray(new String[c.size()]);
System.out.println("b数组内容有:" + Arrays.toString(b));
// 8、public boolean addAll(Collection<? extends E> c):把一个集合的全部数据倒入到另一个集合中去
Collection<String> c1 = new ArrayList<>();
c1.add("java1");
c1.add("java2");
Collection<String> c2 = new ArrayList<>();
c2.add("java3");
c2.add("java4");
c1.addAll(c2);
System.out.println("c1数组内容有:" + c1);
System.out.println("c2数组内容有:" + c2);
}
}
运行结果:
86 Collection集合的遍历方式一:迭代器
使用for循环遍历集合的要求:这个集合必须要支持索引。但是Collection集合并未规定集合的索引问题,只有List系列集合才支持索引。所以Collection集合是不支持使用for循环直接进行遍历的!(所以要学习遍历Collection集合的三种方式)
CollectionDemo01.java:
package com.itheima.hello.d2_collection_traverse;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionDemo01 {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>();
c.add("java1");
c.add("java2");
c.add("java3");
System.out.println(c);
Iterator<String> c1 = c.iterator();
while (c1.hasNext()){
// String c2 = c1.next();
// System.out.println(c2);
System.out.println(c1.next()); // 一定是while处问一次取一次
// System.out.println(c1.next()); // 切记此处循环仅可输出一次c1.next(),否则会报错
}
}
}
运行结果:
87 Collection集合的遍历方式二:增强for
可以直接输入”集合或数组的变量名称.for + 回车“一键生成增强for循环框架
CollectionDemo02.java:
package com.itheima.hello.d2_collection_traverse;
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo02 {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>();
c.add("java1");
c.add("java2");
c.add("java3");
System.out.println(c);
// 可以输入”c.for + 回车“快速生成框架
for (String s : c) {
System.out.println(s);
}
String[] names = {"迪利纳扎", "费尔巴哈"};
// 可以输入”names.for + 回车“快速生成框架
for (String name : names) {
System.out.println(name);
}
}
}
运行结果:
88 Collection集合的遍历方式三:lambda表达式
CollectionDemo03.java:
package com.itheima.hello.d2_collection_traverse;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;
public class CollectionDemo03 {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>();
c.add("java1");
c.add("java2");
c.add("java3");
c.add("java4");
System.out.println(c);
/*
c.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
c.forEach((String s) -> {
System.out.println(s);
});
c.forEach( s -> {
System.out.println(s);
});
c.forEach( s -> System.out.println(s) );
*/
c.forEach( System.out::println );
}
}
运行结果:
89 遍历集合的案例
Movie.java:
package com.itheima.hello.d2_collection_traverse;
public class Movie {
private String name;
private double score;
private String actor;
public Movie() {
}
public Movie(String name, double score, String actor) {
this.name = name;
this.score = score;
this.actor = actor;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public String getActor() {
return actor;
}
public void setActor(String actor) {
this.actor = actor;
}
@Override
public String toString() {
return "Movie{" +
"name='" + name + '\'' +
", score=" + score +
", actor='" + actor + '\'' +
'}';
}
}
CollectionTest04.java:
package com.itheima.hello.d2_collection_traverse;
import java.util.ArrayList;
import java.util.Collection;
/*
* 目标:完成电影信息的展示。
* new Movie("《肖生克的救赎》", 9.7, "罗宾斯")
* new Movie("《霸王别姬》", 9.6, "张国荣、张丰毅")
* new Movie("《阿甘正传》", 9.5, "汤姆.汉克斯")
* */
public class CollectionTest04 {
public static void main(String[] args) {
// 1、创建一个集合容器负责存储多部电影对象
Collection<Movie> movies = new ArrayList<>();
movies.add(new Movie("《肖生克的救赎》", 9.7, "罗宾斯"));
movies.add(new Movie("《霸王别姬》", 9.6, "张国荣、张丰毅"));
movies.add(new Movie("《阿甘正传》", 9.5, "汤姆.汉克斯"));
System.out.println(movies);
for (Movie movie : movies) {
System.out.println("电影名称:" + movie.getName());
System.out.println("电影评分:" + movie.getScore());
System.out.println("演员列表:" + movie.getActor());
}
}
}
运行结果: