day24【枚举&正则表达式】
反馈和复习
多态代理还是不熟悉
复习:动态代理
a.给为一个目标类对象,在程序运行期间,动态的生成一个代理类对象
b.代理类对象可以拦截调用所有方法,可以根据我们的需求对方法进行增强,减弱,直接不让调用
c.动态代理回顾:
public class DynamicProxyDemo {
public static void main(String[] args) {
//1.ArrayList
ArrayList<String> list = new ArrayList<String>();
list.add("java");
list.add("php");
list.add("c++");
//2.使用动态代理
List<String> listProxy = (List<String>) Proxy.newProxyInstance(DynamicProxyDemo.class.getClassLoader(), list.getClass().getInterfaces(), new InvocationHandler() {
//我们调用生成的代理对象的任何方法,都会被invoke方法拦截!!
//Object proxy 代理对象(我们一般用不到)
//Method method 拦截到的方法
//Object[] args 拦截到的方法的参数
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//按照我们自己的需求
String name = method.getName();
//1.拦截add方法
if ("add".equals(name)) {
throw new UnsupportedOperationException("暂时不支持添加操作!");
// System.out.println("暂时不支持添加操作!");
} else {
//2.别的方法直接调用真实对象的方法
Object v = method.invoke(list,args);
return v;
}
}
});
//3.试一试
listProxy.add("android");
String str = listProxy.get(1);
System.out.println(str);
}
}
今日内容
1.枚举(在Java中用的是很多的)
2.JDK8的新特性(默认方法,Lambda,Stream流)
了解即可: 方法引用,Base64用于字符串编码
3.正则表达式(理解)
第一章 枚举【理解】
1. 不使用枚举存在的问题
public class TestPerson {
public static void main(String[] args) {
//1.创建对象
Person p1 = new Person("张三","妖");
System.out.println(p1);
//2.再创建对象
Person p2 = new Person("王五","xxx");
System.out.println(p2);
//此时,我们的性别由于是String类型,那么赋值任意的字符串均可
//但是性别也有应该有要求,"男","女","妖"
//这就是不使用枚举可能出现的问题
}
}
2. 枚举的作用与应用场景
什么是枚举: 所谓的枚举就是把所有可能的情况一一列举出来
什么时候使用枚举: 当某个数据的值是固定有限的,那么我们就可以使用枚举把其值一一列举出来!
3. 枚举的基本语法
-
定义枚举的格式
public enum 枚举名{ //枚举项 枚举项1,枚举项2,...,枚举项n; } /** * 性别的枚举 */ public enum Sex { /** * Male 男性 * Female 女性 * Yao 妖性 */ Male,Female,Yao; }
-
枚举的入门案例
public class Person { private String name; //以前的性别sex是String类型,导致任何值都可以 //private String sex; //现在我们已经有枚举类型 private Sex sex; public Person() { } public Person(String name, Sex sex) { this.name = name; this.sex = sex; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", sex='" + sex + '\'' + '}'; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Sex getSex() { return sex; } public void setSex(Sex sex) { this.sex = sex; } } public class TestPerson { public static void main(String[] args) { //1.创建对象 // Person p1 = new Person("张三","妖"); Person p1 = new Person("张三",Sex.Male); System.out.println(p1); //2.再创建对象 // Person p2 = new Person("王五","xxx"); Person p2 = new Person("王五",Sex.Female); System.out.println(p2); } }
-
枚举的本质
枚举的本质其实就是一个类,枚举项的本质其实当前类的一个对象 /** * 性别的枚举 */ public enum Sex { Male,Female,Yao; } 本质===> public final class Sex extends java.lang.Enum<Sex>{ public static final Sex Male = new Sex(); public static final Sex Female = new Sex(); public static final Sex Yao = new Sex(); 构造方法是私有化的 private Sex(){} } 枚举本质是一个类,那么我们就可以在枚举中添加各种成员变量,成员方法,构造方法等!!! 成员变量和成员方法和普通类没有区别!! 构造方法: a.必须是私有的 b.使用时 枚举项(参数); public enum Sex { Male(10),Female(20),Yao(30); //既然枚举是一个类,那么我们就可以添加我们喜欢的成员变量和成员方法和构造方法 private int age; public void showAge(){ System.out.println(age); } private Sex(){} private Sex(int age){ this.age = age; } }
-
枚举的应用场景
枚举表示性别: public enum Sex { MAIL, FEMAIL; } 枚举表示方向: public enum Orientation { UP, RIGHT, DOWN, LEFT; } 枚举表示季度: public enum Season { SPRING, SUMMER, AUTUMN, WINTER; }
第二章 JDK8的其他新特性【了解】
2.1 方法引用
-
方法引用介绍
所谓的方法引用,就是把已经存在的方法,直接拿过来用!! 当我们可以一个函数式接口类型赋值时,我们赋值该接口的实现类对象,也可以赋值该接口的匿名内部类对象,也可以赋值符合接口的Lambda表达式,也可以使用方法引用
public class Dog { public static void bark() { System.out.println("方法执行了...汪汪汪.."); } public void bark1() { System.out.println("方法执行了...汪汪汪.."); } } public class MethodReferencesDemo { public static void main(String[] args) { //1.创建一个线程,使用实现的方法 //a.使用接口的实现类对象,给Runnable接口类型赋值 new Thread(new MyRunnable()).start(); //b.使用接口的匿名内部类对象,给Runnable接口类型赋值 new Thread(new Runnable() { @Override public void run() { System.out.println("线程执行了..."); } }).start(); //c.使用Lambda,直接给Runnable接口类型赋值 new Thread(()->System.out.println("线程执行了...")).start(); //d.把已经存在的方法直接引用过来 //new Thread(Dog::bark).start(); //通过类名引用静态方法 Dog dd = new Dog(); new Thread(dd::bark1).start(); //通过对象名引用成员方法 } } class MyRunnable implements Runnable{ @Override public void run() { System.out.println("线程执行了..."); } }
-
方法引用基本使用格式
通过类名引用其中的静态方法 类名::静态方法名 通过对象引用其中的普通方法 对象名::普通方法名 通过类名引用其构造方法: 类名::new Person o = new Person(); 通过数组引用其构造方法: 数据类型[]::new int[] arr = new int[10];
-
System.out.println这个方法引用的代码演示
public class SystemOutPrintlnDemo { public static void main(String[] args) { List names = new ArrayList(); names.add("大明"); names.add("二明"); names.add("小明"); //.StreamAPI中 names.stream().forEach(new Consumer<String>() { @Override public void accept(String o) { System.out.println(o); } }); names.forEach(new Consumer<String>() { @Override public void accept(String o) { System.out.println(o); } }); names.forEach(o -> System.out.println(o)); // System.out.println("hello"); names.forEach(System.out::println); } }
2.2 Base64
-
什么是Base64
一种常见的编码方案
-
Base64内嵌类和方法
Decoder和Encoder UrlDecoder和UrlEncoder MimeDecoder和MimeDecoder String encodeToString(byte[] bs); //编码 byte[] decode(String str);//解码
-
Base64演示
public class Base64Demo { public static void main(String[] args) { //1.Base64提供了三种编码器和解码器 //a.基本的编码和解码 String encodeToString = Base64.getEncoder().encodeToString("HelloWorld".getBytes()); System.out.println(encodeToString); byte[] bytes = Base64.getDecoder().decode(encodeToString); System.out.println(new String(bytes)); //b.url的编码和解码 String encodeToString1 = Base64.getUrlEncoder().encodeToString("www.itheima.com".getBytes()); System.out.println(encodeToString1); byte[] bs1 = Base64.getUrlDecoder().decode(encodeToString1); System.out.println(new String(bs1)); //c.MIME类型编码器和解码器 StringBuilder sb = new StringBuilder(); for (int i = 0; i < 10; i++) { UUID uuid = UUID.randomUUID(); sb.append(uuid.toString()); } String content = sb.toString(); // String encodeToString2 = Base64.getMimeEncoder().encodeToString(content.getBytes()); // System.out.println(encodeToString2); String encodeToString2 = Base64.getMimeEncoder(8,"-".getBytes()).encodeToString(content.getBytes()); System.out.println(encodeToString2); byte[] bs2 = Base64.getMimeDecoder().decode(encodeToString2); System.out.println(new String(bs2)); } }
第三章 正则表达式【理解】
1. 正则表达式的概念及演示
案例:
下面的程序让用户输入一个QQ号码,我们要验证:
QQ号码必须是5--15位长度
而且必须全部是数字
而且首位不能为0
public class TestDemo01 {
public static void main(String[] args) {
// 案例:
// 下面的程序让用户输入一个QQ号码,我们要验证:
// QQ号码必须是5--15位长度
// 而且必须全部是数字
// 而且首位不能为0
//1.输入QQ
System.out.println("请输入您的QQ号码:");
String qq = new Scanner(System.in).next();
//2.判断QQ是否合法
if (qq.length() < 5 || qq.length() > 15) {
System.out.println("您的QQ不合法..");
return;
}
for (int i = 0; i < qq.length(); i++) {
char ch = qq.charAt(i);
if (ch < '0' || ch > '9') {
System.out.println("您的QQ不合法..");
return;
}
}
if (qq.charAt(0) == '0') {
System.out.println("您的QQ不合法");
return;
}
System.out.println("你的QQ是合法的~~");
//3.使用正则
boolean b = qq.matches("[1-9]\\d{4,14}");//matches 匹配
System.out.println(b);
}
}
什么是正则:
正则也是一个字符串,但是里面内容表示某种规则(规则是有具体语法含义)
2. 正则表达式-字符类
1. [abc]:代表a或者b,或者c字符中的一个。
2. [^abc]:代表除a,b,c以外的任何字符。
3. [a-z]:代表a-z的所有小写字符中的一个。
4. [A-Z]:代表A-Z的所有大写字符中的一个。
5. [0-9]:代表0-9之间的某一个数字字符。
6. [a-zA-Z0-9]:代表a-z或者A-Z或者0-9之间的任意一个字符。
7. [a-dm-p]:a 到 d 或 m 到 p之间的任意一个字符。
//正则的字符类
public class TestDemo02 {
public static void main(String[] args) {
String str = "aad";
//1.验证str是否以h开头,以d结尾,中间是a,e,i,o,u中某个字符
System.out.println("1." + str.matches("h[aeiou]d"));
//2.验证str是否以h开头,以d结尾,中间不是a,e,i,o,u中的某个字符
System.out.println("2." + str.matches("h[^aeiou]d"));
//3.验证str是否a-z的任何一个小写字符开头,后跟ad
System.out.println("3." + str.matches("[a-z]ad"));
//4.验证str是否以a-d或者m-p之间某个字符开头,后跟ad
System.out.println("4." + str.matches("[a-dm-p]ad"));
}
}
3. 正则表达式-逻辑运算符
1. &&:并且
2. | :或者
/**
* 正则表达式逻辑运算符类
*/
public class TestDemo03 {
public static void main(String[] args) {
String str = "bad";
//1.要求字符串是否是除a、e、i、o、u外的其它小写字符开头,后跟ad
System.out.println("1." + str.matches("[a-z&&[^aeiou]]ad"));
//2.要求字符串是aeiou中的某个字符开头,后跟ad
System.out.println("2." + str.matches("[a|e|i|o|u]ad"));
}
}
4. 正则表达式-预定义字符
1. "." : 匹配任何字符。
2. "\d":任何数字[0-9]的简写;
3. "\D":任何非数字[^0-9]的简写;
4. "\s": 空白字符:[ \t\n\x0B\f\r] 的简写
5. "\S": 非空白字符:[^\s] 的简写
6. "\w":单词字符:[a-zA-Z_0-9]的简写
7. "\W":非单词字符:[^\w]
/**
* 正则表达式-预定义字符
*/
public class TestDemo04 {
public static void main(String[] args) {
String str = "had.";
//1.验证str是否3位数
System.out.println("1." + str.matches("\\d\\d\\d"));
//2.验证手机号:1开头,第二位:3/5/8,剩下9位都是0-9的数字
System.out.println("2." + str.matches("1[3|5|8]\\d\\d\\d\\d\\d\\d\\d\\d\\d"));
//3.验证字符串是否以h开头,以d结尾,中间是任何字符 str = "had";//要验证的字符串
System.out.println("3." + str.matches("h.d"));
//4.验证str是否是:had.
System.out.println("4." + str.matches("had\\."));
}
}
5. 正则表达式-数量词
1. X? : 0次或1次
2. X* : 0次到多次
3. X+ : 1次或多次
4. X{n} : 恰好n次
5. X{n,} : 至少n次
6. X{n,m}: n到m次(n和m都是包含的)
public class TestDemo05 {
public static void main(String[] args) {
String str = "221234567";
//1.验证str是否是三位数字
System.out.println("1." + str.matches("\\d{3}"));
//2.验证str是否是2位数数字以及以上
System.out.println("2." + str.matches("\\d{2,}"));
//3.验证str是否是手机号: str = "13813183388";
System.out.println("3." + str.matches("1[3|6|8]\\d{9}"));
//4.验证小数:必须出现小数点,但是只能出现1次
// 3.1 4.25 1314.1516
System.out.println("4." + str.matches("\\d+\\.\\d+"));
//5.验证小数:小数点可以不出现,也可以出现1次
System.out.println("5." + str.matches("\\d+\\.?\\d+"));
//6.验证小数:要求匹配:3、3.、3.14、+3.14、-3. s2 = "-3.";
System.out.println("6." + str.matches("[+-]\\d+\\.?\\d*"));
//7.验证qq号码:1).5--15位;2).全部是数字;3).第一位不是0
System.out.println("7." + str.matches("[1-9]\\d{4,14}"));
}
}
6. 正则表达式-分组括号( )
/**
* 正则表达式-分组()
*/
public class TestDemo06 {
public static void main(String[] args) {
String str = "DG8FV-B9TKY-FRT9J-99899-XPQ4G";
//验证这个序列号:分为5组,每组之间使用-隔开,每组由5位A-Z或者0-9的字符组成
System.out.println(str.matches("([A-Z0-9]{5}-){4}[A-Z0-9]{5}"));
}
}
7. String的split方法
public String[] split(String regex); 可以使用正则表达式来切换字符串
/**
* 正则表达式-split方法
*/
public class TestDemo07 {
public static void main(String[] args) {
String str = "18,,4,,,567,,,,99,56";
//切割
String[] nums = str.split(",+");
//打印
for (String num : nums) {
System.out.println(num);
}
}
}
8. String类的replaceAll方法
public String replaceAll(String regex,String newStr);//将当前字符串中的旧串替换为新串,其他旧串可以使用正则去匹配
/**
* 正则表达式-replaceAll
*/
public class TestDemo08 {
public static void main(String[] args) {
//将下面字符串中的"数字"替换为"*"
String str = "jfdk432jfdk2jk24354j47jk5l31324";
//将每个数字,都替换为一个*号
String newStr1 = str.replaceAll("\\d", "*");
System.out.println(newStr1);
//将所有相邻的数字,只替换为一个*
String newStr2 = str.replaceAll("\\d+", "*");
System.out.println(newStr2);
}
}
总结:
能够定义枚举
定义:
public enum 枚举名{
枚举项1,枚举项2,枚举项3....枚举项n;
}
枚举名 变量名 = 枚举名.枚举项1;
Sex sex = Sex.MALE;
能够使用四种方法的引用
集合对象.foreach(System.out::println);
其他方式我们作为了解,可以参考"方法引用完整版扩展视频"
能够使用Base64对基本数据、URL和MIME类型进行编解码
public String encodeToString(byte[] bs);
public byte[] decode(String str);
能够理解正则表达式的作用
"匹配"字符串
能够使用正则表达式的字符类
[abc][^abc][0-9][a-z][A-Z][0-9a-zA-Z][a-dm-px-z]
能够使用正则表达式的逻辑运算符
&& |
能够使用正则表达式的预定义字符类
\\d \\w .
能够使用正则表达式的数量词
X?
X*
X+
X{n}
X{n,}
X{n,m}
能够使用正则表达式的分组
(...){2}
能够在String的split方法中使用正则表达式
能够在String的replaceAll方法中使用正则表达式
作业: 把学生管理系统写一遍