概述
Day11
Object
含义:所有类的基类/超类
理解:一个类没有明确继承的父类,都默认继承Object
equals():判断两个对象的地址是否相同
public boolean equals(Object obj){
return (this == obj);
}
getClass():获取类的字节码文件对象
hashCode():获取对象的hash码
hash码:对象的地址 + 散列算法(注意:hash码不等于内存地址)
toString():将对象转换为字符串格式,打印对象,默认调用toString方法
public String toString(){
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
//getClass().getName() 获取到当前类的全路径名
//Integer.toHexString(hashCode()) 将十进制的hash码转换为十六进制
类: A.java
对象:equals(): Test01.java
对象:equals()和getClass(): Test02.java
对象:hashCode(): Test03.java
对象: toString(): Test04.java
深入Object
含义:Object作为所有类的超类,起到标杆作用
equals()标杆作用:判断两个对象是否相同
理解:Object不同的子类,判断两个对象的方式是不一样的,所以在子类中重写该方法,定义适合当前子类判断两个对象的规则
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2TuP0TGq-1644159259789)(D:2113java_workspaceDay11Day11上午equals理解图.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D0OCcyR8-1644159259789)(D:2113java_workspaceDay11Day11上午equals深入理解图.png)]
toString()标杆作用:打印对象中的数据
理解:Object不同的子类用于不同的属性,所以在子类中重写该方法,返回想要展示的属性即可
需求:模拟银行的用户类
User类: User.java
对象: Test01.java
需求:模拟千锋的学生类
判断两个学生是否相同:班级号 + 学号
总结 - 编写实体类的步骤:
1.成员变量
2.私有化成员变量
3.无参构造
4.有参构造
5.get/set方法
6.根据需求 – 重写equals
7.根据需求 – 重写toString
Student类: Student.java
对象: Test01.java
深入Object — String
MyString 类: MyString.java
对象: Test01.java
final – 最终的
1.修饰类:该类不能被继承
2.修饰方法:该方法不能被重写
3.修饰变量:该变量变成常量不能被重新赋值,该常量存储在常量池中,直到项目结束才会被销毁
A类: A.java
B extends A: B.java
对象: Test01.java
抽象类及抽象方法
抽象类:使用abstract修饰
抽象方法:使用abstract修饰,该方法没有代码块
抽象方法的应用场景:
编写一个类,该类里的某个方法不太好实现,又觉得该方法应该在这个类里,就把该方法设置成抽象方法,交给非抽象的子类去重写/实现即可,该抽象方法所在的类必须是抽象类
需求:编写人类、中国人、日本人
人类(抽象类):
-
属性:姓名、性别、年龄
-
方法:吃饭饭(抽象方法)、睡觉觉
日本人 extends 人类:
-
属性:年号
-
方法:拍电影
-
重写父类的吃饭饭
中国人(抽象类) extends 人类:
-
属性:身份证
-
方法:打太极、爱好(抽象方法)
四川人 extends 中国人
-
属性:无
-
方法:重写吃饭饭、重写爱好
Person类: Person.java
Chinese类: Chinese.java
Japanese类: Japanese.java
SiChuan类: SiChuan.java
GuangDong类: GuangDong.java
对象: Test01.java
深入抽象类及抽象方法
1.抽象类中只能有抽象方法?
不是,抽象类可以有抽象方法、构造方法、成员方法、静态方法
2.抽象类中不可以没有抽象方法?
可以,但是毫无意义
3.如果父类是抽象类,则子类必须实现父类的抽象方法?
不一定,
子类如果是抽象类,可以不实现父类的抽象方法,交给子类的非抽象类的子类去实现
子类如果不是抽象类,则必须实现父类的抽象方法
4.抽象类不能有构造方法?
可以
5.可以使用new关键字来创建抽象类对象?
不可以,创建的是匿名内部类的对象,抽象类是不能有对象的
创建匿名内部类(匿名子类)的对象
1.创建匿名内部类
2.继承Chinese,重写父类的抽象方法
3.创建匿名内部类的对象
4.将匿名内部类对象的地址赋值给父类的引用(多态)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f8VBgAH9-1644159259790)(D:2113java_workspaceDay11Day11下午抽象类的匿名内部类的理解图.png)]
需求:编写人类、中国人、日本人
人类(抽象类):
-
属性:姓名、性别、年龄
-
方法:吃饭饭(抽象方法)、睡觉觉
日本人 extends 人类:
-
属性:年号
-
方法:拍电影
-
重写父类的吃饭饭
中国人(抽象类) extends 人类:
-
属性:身份证
-
方法:打太极、爱好(抽象方法)
四川人 extends 中国人
-
属性:无
-
方法:重写吃饭饭、重写爱好
Person类: Person.java
Chinese类: Chinese.java
Japanese类: Japanese.java
SiChuan类: SiChuan.java
GuangDong类: GuangDong.java
对象: Test01.java
接口
知识点:接口
含义:特殊的抽象类
理解:
1.接口中只能有静态常量(默认添加 public static final)和抽象方法(默认添加 abstract)
2.JDK1.8开始接口中允许有默认方法和静态方法(JDK1.8新特性)
接口I1: I1.java
A implements I1: A.java
对象: Test01.java
知识点:接口的应用
理解:制定标准
需求:模拟用户操作
接口IUserService: IUserService.java
serServiceImpl implements IUserService: UserServiceImpl.java
对象: Test01.java
深入接口
类 - 接口的关系
类 - 类:单继承
类 - 接口:多实现
接口与接口:多继承
1.一个类可以实现多个接口?
可以的
2.一个接口可以实现多个接口?
不可以
3.接口里面的方法不一定都是抽象的?
对的,JDK1.8开始接口中允许使用静态方法和默认方法
4.接口解决了类的单继承问题?
是的
5.一个类是否可以继承一个类并同时实现多个接口?
可以
6.接口可以new对象?
不可以,创建时匿名内部类的对象
创建匿名内部类的对象
1.底层创建匿名内部类
2.实现I1接口中的抽象方法
3.创建匿名内部类的对象
4.将匿名内部类对象的地址赋值给接口的引用
7.接口里面的是抽象方法,想要重写接口里面的方法:
让类去实现这个接口然后在类里面重写接口里面的方法。
要在对象里面重写接口里面的方法,就通过匿名内部类的形式创建接口的对象,让对象去重写接口里面的方法。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sfj0ch59-1644159259790)(D:2113java_workspaceDay11Day11下午接口的匿名内部类理解图.png)]
7.一个类实现了多个接口,多个接口中的方法名重复,是什么情况?
只实现一个方法
I1接口: I1.java
I2接口: I2.java
I3 extends I4,I5: I3.java
I4接口: I4.java
I5接口: I5.java
A extends Object implements I1,I2,I3: A.java
对象: Test01.java
Day12
多态
类的多态
子类对象指向父类引用
理解:父类引用中存的是子类对象在堆中地址
OCP – 开闭原则
O - open - 在需求更改时,对于创建类是欢迎的
C - close - 在需求更改时,对于修改原有类是拒绝的
P - principle(原则)
package com.qf.test01;
public class Test01 {
public static void main(String[] args) {
/**
* 知识点:多态
*
* 需求:老师骑着自行车上班
* 分析:老师类、自行车类
*
* 需求升级:自行车 --> 小汽车
* 步骤:
* 1.创建Car类,添加open、close方法
* 2.在Teacher类中,添加start、stop方法 -- 改动原有类的结构
* 需求升级:自行车 --> 小汽车 --> 飞机
* 步骤:创建Plane类,继承Vehicle类
*/
Teacher t = new Teacher();
Vehicle v = new Plane();
v这个引用存的是Plane的对象在堆中开辟的地址
t.start(v);
System.out.println("欣赏沿途的风景...");
t.stop(v);
}
}
交通工具Vehicle 类: Vehicle.java
Plane类: Plane.java
Car类: Car.java
Bick类: Bick.java
Teacher类: Teacher.java
对象: Test01.java
接口的多态
实现类的对象指向接口的引用
理解:接口的引用存储的是实现类对象在堆中开辟的地址
需求:模拟电脑连接外部设备(鼠标、键盘、硬盘)
IUSB类: IUSB.java
Mouse类: Mouse.java
Keyboard类: Keyboard.java
Disk类: Disk.java
Computer类: Computer.java
对象: Test01.java
多态的实际应用
需求:设计一个方法输入编号,返回对应的动物对象
1-返回狗类对象
2-返回猫类对象
3-返回猪类对象
Animal类: Animal.java
Dog类: Dog.java
Cat类: Cat.java
Pig类: Pig.java
对象: Test01.java
对象转型
自动转型(向上转型)
注意:
1.向上转型其实就是类的多态
2.可以调用父类非私有化的属性
3.可以调用父类非私有化的方法
4.不可以调用子类的属性
5.不可以调用子类的方法
6.可以调用子类重写父类的方法
多态的优点:
遵循了OCP原则
多态的缺点:
不可以调用子类的属性和方法
A类: A.java
B extends A: B.java
对象: Test01.java
强转转型(向下转型)
强转转型(向下转型):父类类型 转 子类类型
注意:
1.向下转型有风险,ClassCastException - 类型转型异常
2.先向上转型,再向下转型
Animal类: Animal.java
Dog类: Dog.java
Cat类: Cat.java
对象: Test01.java
MyString类: MyString.java
对象: Test01.java
内部类
知识点:内部类
含义:一个类中还去声明了另一个类
分类:
1.成员内部类
2.静态内部类
3.接口内部类
4.局部内部类
5.匿名内部类
成员内部类
可以调用外部类所有的属性
创建成员内部类的对象
Inner inner = new Outter().new Inner();
调用方法
inner.method();
Outter类(含成员内部类Inner): Outter.java
对象: Test01.java
静态内部类
注意:不用创建外部类对象,直接使用外部类类名.内部类的构造方法
总结:只能调用外部类的静态属性
创建静态内部类的对象
Inner inner = new Outter.Inner();
调用方法
inner.method();
Outter类(含静态内部类Inner): Outter.java
对象: Test01.java
接口内部类
注意:默认使用static修饰
总结:创建接口内部类的方式和静态内部类一样
创建接口内部类的对象
Inner inner = new I1.Inner();
调用方法
inner.method();
I1接口(含接口内部类Inner): I1.java
对象: Test01.java
局部内部类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cUTYtvDt-1644159259792)(D:2113java_workspaceDay12Day12下午局部内部类扩展图.png)]
注意:局部内部类相当于局部变量,不能使用访问修饰符修饰
总结:局部内部类使用外部类的局部变量,JDK1.8开始该变量会自动使用final修饰
创建外部类对象
Outter outter = new Outter();
调用方法
outter.outterMethod();
Outter类(含局部内部类Inner): Outter.java
对象: Test01.java
Outter类(含局部内部类Inner): Outter.java
对象: Test01.java
匿名内部类
类的匿名内部类
接口的匿名内部类
匿名内部类
package com.qf.outter_inner_07;
public class Test01 {
public static void main(String[] args) {
//匿名内部类
//1.创建匿名类,继承A类重写method方法
//2.创建匿名类的对象
//3.赋值给父类的引用
A a = new A() {
@Override
public void method() {
}
};
//匿名内部类
//1.创建匿名类,实现I1接口中的method方法
//2.创建匿名类的对象
//3.赋值给接口的引用
I1 i1 = new I1() {
@Override
public void method() {
}
}
}
}
A类: A.java
接口: I1.java
对象: Test01.java
面向对象版本五子棋
类: GoBang.java
对象: Test01.java
学生管理系统
Student.java
StuInfoUtils.java
IStudentManagerSystem.java
StudentManageSystemImpl.java
Main.java
StuInfoType.java
Day13
包装类
package com.qf.test01;
import java.util.Arrays;
public class Test01 {
public static void main(String[] args) {
知识点:包装类
含义:8种基本数据类型对应的类
出现原因:Java为纯面向对象语言(万物皆对象),8种基本数据类型不能创建对象,破坏了Java为纯面向对象语言的特征,所以Java又提供了8种基本数据类型对应的类,这种类叫做包装类/封装类
包装类及继承关系:
* 基本数据类型 包装类
* byte Object.Number.Byte
* short Object.Number.Short
* int Object.Number.Integer
* long Object.Number.Long
* float Object.Number.Float
* double Object.Number.Double
* char Object.Character
* boolean Object.Boolean
手动装箱 -- valueOf():基本数据类型 -> 包装类
int i = 100;
Integer integer = Integer.valueOf(i);
System.out.println(integer);
手动拆箱 -- intValue():包装类 -> 基本数据类型
int intValue = integer.intValue();
System.out.println(intValue);
JDK1.5开始有自动装箱和自动拆箱的功能
自动装箱:基本数据类型 -> 包装类
int i = 100;
Integer integer = i;//底层实现:Integer.valueOf(i);
System.out.println(integer);
自动拆箱:包装类 -> 基本数据类型
int intValue = integer;//底层实现:integer.intValue();
System.out.println(intValue);
获取数值型的区间
System.out.println(Byte.MAX_VALUE);
System.out.println(Byte.MIN_VALUE);
System.out.println(Integer.MAX_VALUE);//(1<<31)-1
System.out.println(Integer.MIN_VALUE);//1<<31
String str = "123";
int num = Integer.parseInt(str);
System.out.println(num);
需求:将String[] ss = {"1","2","3","4","5","6"}转换为int数组
String[] ss = {"1","2","3","4","5","6"};
int[] is = new int[ss.length];
for (int i = 0; i < ss.length; i++) {
//获取字符串数组中的元素
String element = ss[i];
//将元素转换为int值
int num = Integer.parseInt(element);
//赋值给int数组
is[i] = num;
}
System.out.println(Arrays.toString(is));
}
}
手撕包装类源码
包装类: MyInteger.java
对象: Test01.java
字符串类
String的使用
String是不可变类,即一旦一个String对象被创建, 包含在这个对象中的字符序列是不可改变的, 直至该对象被销毁。 String类是final类,不能有子类。
package com.qf.test03;
public class Test01 {
public static void main(String[] args) {
String str = "123abc";
str = str.concat("DEF123");//在此字符串末尾追加子字符串,并返回新的字符串
str = str.substring(3);//从下标处截取到字符串末尾,并返回新的字符串
str = str.substring(1, 6);//从开始下标处(包含)截取到结束下标处(不包含),并返回新的字符串
str = str.toUpperCase();//转大写,并返回新的字符串
str = str.toLowerCase();//转小写,并返回新的字符串
str = " 123 a b cD EF 123 ";
str = str.trim();//去掉首尾空格,并返回新的字符串
str = str.replace('2', '-');//替换字符,并返回新的字符串
str = str.replace("1-3", "钟燕");//替换字符串,并返回新的字符串
//把空格字符串替换成 空内容的字符串
str = str.replace(" ", "");//替换字符串,并返回新的字符串
str = str.replaceFirst("燕", "馗");//替换第一个出现的字符串,并返回新的字符串
System.out.println("判断两个字符串是否相同(区分大小写):" + str.equals("钟馗abcDEF钟燕"));//true
System.out.println("判断两个字符串是否相同(不区分大小写):" + str.equalsIgnoreCase("钟馗abcdef钟燕"));//true
System.out.println("判断此字符串是否以某个字符串开头:" + str.startsWith("钟馗"));//true
System.out.println("判断此字符串是否以某个字符串结尾:" + str.endsWith("钟燕"));//true
System.out.println("查询子字符串在此字符串中第一次出现的下标:" + str.indexOf("钟"));//0
System.out.println("查询子字符串在此字符串中最后一次出现的下标:" + str.lastIndexOf("钟"));//8
System.out.println("通过下标获取字符串中对应的字符:" + str.charAt(5));//D
//钟馗abcDEF钟燕
System.out.println(str);
//将其他类型转为字符串
String valueOf1 = String.valueOf(100);
String valueOf2 = String.valueOf(123.12);
String valueOf3 = String.valueOf(true);
System.out.println(valueOf1);
System.out.println(valueOf2);
System.out.println(valueOf3);
//将其他类型转为字符串 -- 更简单的方法
System.out.println('a' + "");
System.out.println(100 + "");
System.out.println(123.12 + "");
System.out.println(true + "");
}
}
深入String
面试题:这段代码在底层生成多少个String对象?
1个(常量池中)
String str1 = "abc";
String str2 = "abc";
面试题:这段代码在底层生成多少个String对象?
3个("abc"一个,new了两个String)
String str1 = new String("abc");
String str2 = new String("abc");
String str1 = "abc";
String str2 = "abc";
System.out.println(str1 == str2);//true
//"ab"和"c"都是字面值常量,在编译时就直接拼接成"abc"
String str3 = "ab" + "c";
System.out.println(str1 == str3);//true
//两个字面值常量,在编译时直接拼接
final String s1 = "ab";
final String s2 = "c";
String str4 = s1 + s2;
System.out.println(str1 == str4);//true
//两个变量拼接底层会创建StringBuilder对象
String s3 = "ab";
String s4 = "c";
String str5 = s3 + s4;//new StringBuilder(s3).append(s4).toString();
System.out.println(str1 == str5);//false
StringBuffer的使用
StringBuffer代表可变的字符序列
StringBuffer称为字符串缓冲区
它的工作原理是:预先申请一块内存,存放字符序列,如果字符序列满了,会重新改变缓存区的大小,以容纳更多的字符序列。StringBuffer是可变对象,这个是String最大的不同
StringBuffer extends AbstractStringBuilder
package com.qf.test03;
public class Test02 {
public static void main(String[] args) {
创建StringBuffer的对象 -- 默认缓冲区大小:16个字符
StringBuffer sb = new StringBuffer();
创建StringBuffer的对象 -- 自定义缓冲区大小:32个字符
StringBuffer sb = new StringBuffer(32);
创建StringBuffer的对象 -- 自定义缓冲区大小:"123abc".length() + 16个字符
StringBuffer sb = new StringBuffer("123abc");
sb.append("DEF123");//在末尾追加
sb.insert(6, "-_-");//在指定下标上插入字符串
sb.setCharAt(7, '+');//替换指定下标上的字符
sb.deleteCharAt(7);//删除指定下标上的字符
sb.delete(3, 6);//从开始下标处(包含)删除结束下标处(不包含)的字符串
sb.replace(3, 5, "ABC");//从开始下标处(包含)替换结束下标处(不包含)的字符串
sb.reverse();//反转字符串
//321FEDCBA321
System.out.println(sb);
}
}
StringBuilder的使用
StringBuilder extends AbstractStringBuilder
StringBuffer extends AbstractStringBuilder
在使用层面上,StringBuilder和StringBuffer没有区别
StringBuilder 是线程不安全的,效率高,单线程下使用
StringBuffer 是线程安全的(因为有上锁解锁的步骤),效率低,多线程下使用
频繁的字符串拼接,请使用StringBuilder或StringBuffer
package com.qf.test03;
public class Test07 {
public static void main(String[] args) {
//System.currentTimeMillis();获取1970.1.1 0:0:0到现在的毫秒数(1000毫秒=1秒)
long startTime = System.currentTimeMillis();
String str = "钟燕小可爱,";
for (int i = 0; i < 10000; i++) {
str += "爱你~~~";
//str = str+"爱你~~~";
//str = new StringBuilder(str).append("爱你~~~").toString();
}
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);//272毫秒
long startTime = System.currentTimeMillis();
StringBuilder sb = new StringBuilder("钟燕小可爱,");
for (int i = 0; i < 10000; i++) {
sb.append("爱你~~~");
}
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);//3毫秒
}
}
Day14
date
知识点:日期时间类
Date:日期类
SimpleDateFormat:格式化日期类
Calendar:日历类
总结:
Date + SimpleDateFormat 联合使用,获取想要的日期格式
Calendar:获取某个日期信息
package com.qf.date;
import java.util.Date;
public class Test01 {
public static void main(String[] args) {
Date date = new Date();
//星期 月份 日 时:分:秒 时区 年份
//Thu Dec 30 10:27:37 CST 2021
System.out.println(date);
//从1970.1.1 0:0:0 + 时区 往后推1000毫秒
Date date = new Date(1000);
System.out.println(date);
}
}
package com.qf.date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test02 {
public static void main(String[] args) throws ParseException {
//创建格式化日期类的对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
//日期类对象 --> 字符串
String format = sdf.format(new Date());
System.out.println(format);
//字符串 --> 日期类对象
Date date = sdf.parse("2021年12月30日 10:33:70");
System.out.println(date);
}
}
package com.qf.date;
import java.util.Calendar;
public class Test03 {
public static void main(String[] args){
//获取日历类的对象
Calendar c = Calendar.getInstance();
//获取日历信息
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH) + 1;
int day = c.get(Calendar.DAY_OF_MONTH);
int hour = c.get(Calendar.HOUR);
int minute = c.get(Calendar.MINUTE);
int second = c.get(Calendar.SECOND);
System.out.println(year);
System.out.println(month);
System.out.println(day);
System.out.println(hour);
System.out.println(minute);
System.out.println(second);
}
}
math
含义:数学类,提供了基本的运算和几何函数
注意:Math是final类,并且该类所有的属性和方法都是静态的
把Math类中所有的静态属性和静态方法都导入到当前类
让这些静态属性和静态方法成为当前类自己的静态属性和静态方法
静态导入的缺点:可读性较差,如果当前类自身就有abs方法,就会就近调用
package com.qf.math;
public class Test01 {
public static void main(String[] args) {
System.out.println("求平方:" + Math.pow(3, 2));//9.0
System.out.println("求平方根:" + Math.sqrt(9.0));//3.0
System.out.println("求最大值:" + Math.max(10, 20));//20
System.out.println("求最小值:" + Math.min(10, 20));//10
System.out.println("向上取整(天花板):" + Math.ceil(1.001));//2.0
System.out.println("向下取整(地板):" + Math.floor(1.999));//1.0
System.out.println("四舍五入:" + Math.round(1.49));//2
System.out.println("随机值:" + Math.random());//0(包含)~1(不包含)
System.out.println("绝对值:" + Math.abs(-100));//100
}
}
面试题:Math.abs()是否会返回负数
System.out.println("绝对值:" + Math.abs(Integer.MAX_VALUE+1));
package com.qf.math;
import static java.lang.Math.*;
public class Test03 {
public static void main(String[] args) {
System.out.println("求平方:" + pow(3, 2));//9.0
System.out.println("求平方根:" + sqrt(9.0));//3.0
System.out.println("求最大值:" + max(10, 20));//20
System.out.println("求最小值:" + min(10, 20));//10
System.out.println("向上取整(天花板):" + ceil(1.001));//2.0
System.out.println("向下取整(地板):" +floor(1.999));//1.0
System.out.println("四舍五入:" + round(1.49));//2
System.out.println("随机值:" + random());//0(包含)~1(不包含)
//静态导入的缺点:可读性较差,如果当前类自身就有abs方法,就会就近调用
System.out.println("绝对值:" + abs(-100));//100
}
public static int abs(int i){
return -888;
}
}
regex
正则表达式
用来描述或者匹配一系列符合某个语句规则的字符串
案例:把一个字符串中带电话号码替换成130****1111
package com.qf.regex;
public class Test01 {
public static void main(String[] args) {
String str = "小红13012341111 小绿13922221234";
//正则表达式
String regex = "(1\d{2})(\d{4})(\d{4})";
//替换
String replaceAll = str.replaceAll(regex,"$1****$3");
System.out.println(replaceAll);
}
}
Pattern/Matcher
Pattern:代表正则表达式的匹配模式
Matcher:提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持
案例1:校验QQ邮箱
package com.qf.regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test02 {
public static void main(String[] args) {
String email = "1445584980@qq.com";
String regex = "\d{5,10}@qq.com";
//验证email字符串是否匹配regex的正则表达式
//boolean matches = email.matches(regex);
//底层实现:
Pattern pattern = Pattern.compile(regex);//获取正则表达式的对象
Matcher matcher = pattern.matcher(email);//获取匹配结果的对象
boolean matches = matcher.matches();//获取验证结果
System.out.println(matches);
}
}
案例2:分隔路径
package com.qf.regex;
import java.util.regex.Pattern;
public class Test03 {
public static void main(String[] args) {
String str = "C:\资源\日韩\波多野结衣.avi";
String regex = ":?\\";// :\ 或 \
//String[] split = str.split(regex);//分隔字符串
//底层实现:
Pattern pattern = Pattern.compile(regex);
String[] split = pattern.split(str);
for (String s : split) {
System.out.println(s);
}
}
}
案例3:Pattern+Matcher 找到前端代码中的图片路径
package com.qf.regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test04 {
public static void main(String[] args) {
String str = "<img src='hhy/aaa.jpg'/><div><div/> <input type='image' src='submit.gif' /><img src='bbb.jpg'/>";
String regex = "<img\b[^>]*\bsrc\b\s*=\s*('|")?([^'"nrf>]+(\.jpg|\.bmp|\.eps|\.gif|\.mif|\.miff|\.png|\.tif|\.tiff|\.svg|\.wmf|\.jpe|\.jpeg|\.dib|\.ico|\.tga|\.cut|\.pic)\b)[^>]*>";
// System.out.println("在字符串中是否整个匹配:" + matcher.matches());
// System.out.println("在字符串中是否开头就匹配:" + matcher.lookingAt());
// System.out.println("在字符串中是否有包含匹配:" + matcher.find());
//获取正则表达式的对象
Pattern pattern = Pattern.compile(regex);
//获取匹配结果的对象
Matcher matcher = pattern.matcher(str);
//查询匹配结果
while(matcher.find()){
String group = matcher.group(2);
System.out.println(group);
}
}
}
random
随机类
深入Random – 种子数
理解:Random类的随机数都是通过算法得到的,算法中最终要的就是种子数,种子数固定,得到的随机数也是固定的
MyRandom.java
Test01.java
Test02.java
runtime
运行时的类,表示运行时环境
package com.qf.runtime;
public class Test01 {
public static void main(String[] args) {
//获取运行时环境的对象
Runtime run = Runtime.getRuntime();
System.out.println("最大内存:" + run.maxMemory());
System.out.println("闲置内存:" + run.freeMemory());
System.out.println("最大处理数:" + run.availableProcessors());
}
}
package com.qf.runtime;
public class Test02 {
public static void main(String[] args) {
/**
* 知识点:代码性能
* 考虑消耗时长+内存
*/
Runtime run = Runtime.getRuntime();
long startMemory = run.freeMemory();
long startTime = System.currentTimeMillis();
String str = "钟燕小可爱,";
for (int i = 0; i < 10000; i++) {
str += "爱你~~~";
str = str+"爱你~~~";
str = new StringBuilder(str).append("爱你~~~").toString();
}
long endTime = System.currentTimeMillis();
long endMemory = run.freeMemory();
System.out.println("消耗时长:" + (endTime - startTime));//272毫秒
System.out.println("消耗内存:" + (startMemory - endMemory));//-247658072(当内存不够时,gc回收了,导致内存反而变大)
Runtime run = Runtime.getRuntime();
long startMemory = run.freeMemory();
long startTime = System.currentTimeMillis();
StringBuilder sb = new StringBuilder("钟燕小可爱,");
for (int i = 0; i < 10000; i++) {
sb.append("爱你~~~");
}
long endTime = System.currentTimeMillis();
long endMemory = run.freeMemory();
System.out.println("消耗时长:" + (endTime - startTime));//2毫秒
System.out.println("消耗内存:" + (startMemory - endMemory));//196624
}
}
System
package com.qf.system;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Scanner;
public class Test01 {
public static void main(String[] args) {
/**
* 知识点:System的属性
*/
//系统标准的输入流(控制台->程序)
InputStream in = System.in;
Scanner scan = new Scanner(in);
String str = scan.next();
//系统标准的输出流(程序->控制台)
//PrintStream extends FilterOutputStream extends OutputStream
PrintStream ps = System.out;
ps.println(str);
//系统标准的错误输出流(程序->控制台)
//PrintStream extends FilterOutputStream extends OutputStream
PrintStream ps = System.err;
ps.println(str);
//关流(关闭资源)
scan.close();
}
}
package com.qf.system;
public class Test02 {
public static void main(String[] args) {
/**
* 知识点:研究System的out和err
* out是一个线程
* err是另一个线程
* 感受多线程之间争抢CPU资源的场景
*/
System.out.println("小明");
System.err.println("小红");
System.out.println("小强");
}
}
package com.qf.system;
import java.util.Arrays;
import java.util.Properties;
public class Test03 {
public static void main(String[] args) {
/**
* 知识点:System的方法
*/
//退出当前虚拟机,0表示正常退出
System.exit(0);
//获取自1970.1.1 0:0:0到现在的毫秒数
System.out.println(System.currentTimeMillis());
//获取系统的配置文件
Properties properties = System.getProperties();
System.out.println(properties);
//通过key获取value
String value = System.getProperty("os.name");
System.out.println(value);
//拷贝数组
String[] names = {"黄小龙1","黄小龙2","黄小龙3"};
String[] newNames = new String[3];
System.arraycopy(names, 0, newNames, 0, names.length);
System.out.println(Arrays.toString(newNames));
}
}
大数值的运算类
package com.qf.big;
import java.math.BigInteger;
public class Test01 {
public static void main(String[] args) {
/**
* 知识点:整数类型的大数值的运算类 - BigInteger
*/
BigInteger big1 = new BigInteger("1234567890");
BigInteger big2 = new BigInteger("1234567890");
//加法
BigInteger add = big1.add(big2);
System.out.println(add);//2469135780
//减法
BigInteger subtract = big1.subtract(big2);
System.out.println(subtract);//0
//乘法
BigInteger multiply = big1.multiply(big2);
System.out.println(multiply);//1524157875019052100
//除法
BigInteger divide = big1.divide(big2);
System.out.println(divide);//1
}
}
package com.qf.big;
import java.math.BigDecimal;
public class Test02 {
public static void main(String[] args) {
/**
* 知识点:浮点类型的大数值的运算类 - BigDecimal
*/
BigDecimal big1 = new BigDecimal("0.5");
BigDecimal big2 = new BigDecimal("0.4");
//加法
BigDecimal add = big1.add(big2);
System.out.println(add);//0.9
//减法
BigDecimal subtract = big1.subtract(big2);
System.out.println(subtract);//0.1
//乘法
BigDecimal multiply = big1.multiply(big2);
System.out.println(multiply);//0.20
//除法
BigDecimal divide = big1.divide(big2);
System.out.println(divide);//1.25
}
}
package com.qf.big;
import java.math.BigDecimal;
public class Test03 {
public static void main(String[] args) {
/**
* 知识点:浮点类型的大数值的运算类 - BigDecimal
*/
BigDecimal big1 = new BigDecimal("10");
BigDecimal big2 = new BigDecimal("3");
//除法
BigDecimal divide = big1.divide(big2, 2, BigDecimal.ROUND_HALF_UP);
System.out.println(divide);//3.333333
}
}
常用类归纳
1.包装类(熟悉)
出现原因
装箱和拆箱
Integer中的IntegerCache
2.字符串类(熟悉)
String、StringBuilder、StringBuffer
3.正则表达式(了解)
4.日期时间类(了解)
Date + SimpleDateFormat
Calendar
5.Math(了解)
注意:静态导入
6.Random(了解)
注意:种子数
7.Runtime(了解)
8.System(了解)
System.in/out/err
System.arraycopy()
9.大数值运算类(熟悉)
Day15
初识枚举
概念
枚举(enum)全称为 enumeration, 是 JDK 1.5 中引入的新特性。
语法
public enum Color{
//默认添加 public static final Color
RED,GREEN,BLUE;
}
本质
尽管枚举看起来像是一种新的数据类型,实际上,枚举就是一种受限制的类,并且具有自己的方法。一个类有固定的几个对象时,就用枚举代替。创建自己的enum类时,这个类继承自 java.lang.Enum。
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable{
...
}
特点
- 枚举就是一个受限制的类,默认继承Enum
- 枚举的第一行必须定义该枚举类型的对象
- 枚举类型对象默认添加: public static final 类型
- 枚举没有继承明确类(自定义枚举类默认继承Enum,Enum默认继承Object)
- 枚举类不能被继承
- 枚举里可以有构造方法、成员方法、静态方法、抽象方法
- 枚举可以实现接口
- 枚举里没有定义方法,可以在最后一个对象后面加逗号、分号或什么都不加
优势
增强代码可读性
枚举型可直接与数据库交互
switch语句优势
编译优势
(枚举类编译时,没有把常量值编译到代码中,即使常量值发生改变,也不会影响引用常量的类 )
将常量组织起来,统一管理
去除equals两者判断 由于常量值地址唯一,使用枚举可以直接通过“==”进行两个值之间的对比,性能会有所提高
需求:编写季节类(Season),该类只有四个对象(spring,summer,autumn,winter)
类: Season.java
对象: Test01.java
需求:编写季节类(Season),该类只有四个对象(spring,summer,autumn,winter)使用枚举解决这个需求。
类: Season.java 默任添加public static final
对象: Test01.java
枚举的常用方法
方法名 | 解释 |
---|---|
Enum.valueOf(Class enumType, String name) | 根据字符串找到该枚举类中的对象 |
public static void values() | 获取该枚举类对象数组 |
public static void valueOf(String args0) | 根据字符串获取该枚举类中的对象 |
public final String name() | 获取该枚举对象名字 |
public final Class getDeclaringClass() | 获取枚举对象的枚举类型相对应的Class对象 |
public final int hashCode() | 获取该枚举对象的hash值 |
public final int compareTo(E o) | 两个枚举对象进行比较 |
public final boolean equals(Object other) | 比较两个枚举对象是否相同 |
package com.qf.enum02;
public class Test02 {
public static void main(String[] args) {
//将字符串转换为枚举对象(通过字符串找到对应的枚举对象)
Season spring = Enum.valueOf(Season.class, "spring");
System.out.println(spring);
//获取枚举中所有的对象,并返回数组
Season[] seasons = Season.values();
for (Season season : seasons) {
System.out.println(season);
}
//将字符串转换为枚举对象(通过字符串找到对应的枚举对象)
Season spring = Season.valueOf("spring");
System.out.println(spring);//春天 -- 春雨绵绵
//获取枚举对象的名字
String name = spring.name();
System.out.println(name);//spring
//通过枚举类的对象获取到枚举类的字节码文件对象
Class<Season> c = spring.getDeclaringClass();
System.out.println(c);//class com.qf.enum02.Season
}
}
枚举案例
状态机
类: Signal.java
对象: Test01.java
状态码/错误码
场景:做项目(学生管理系统),每个功能都有不同的状态码
添加功能:-1学生信息不合法 -2有该学生 1-添加成功
类: AddStateCode.java
对象: Test01.java
组织枚举
含义:可以将类型相近的枚举通过接口或类组织起来(但是一般用接口方式进行组织)
原因是:
Java接口在编译时会自动为enum类型加上public static修饰符;
Java类在编译时会自动为 enum 类型加上static修饰符;
就是说,在类中组织 enum,如果你不给它修饰为 public,那么只能在本包中进行访问。场景:做项目(学生管理系统),每个功能都有不同的状态码
添加功能:-1学生信息不合法 -2有该学生 1-添加成功
删除功能:-1学生信息不合法 -2没有该学生 1-删除成功
类: StateCode.java
对象: Test01.java
策略枚举
类: Salary.java
对象: Test01.java
枚举工具类 - EnumSet 和 EnumMap
Java 中提供了两个方便操作enum的工具类——EnumSet 和 EnumMap。
EnumSet :枚举类型的高性能 Set实现。它要求放入它的枚举常量必须属于同一枚举类型。
EnumMap :专门为枚举类型量身定做的 Map 实现。虽然使用其它的 Map 实现(如HashMap)也能完成枚举类型实例到值得映射,但是使用 EnumMap 会更加高效,因为它只能接收同一枚举类型的实例作为键值,并且由于枚举类型实例的数量相对固定并且有限,所以 EnumMap 使用数组来存放与枚举类型对应的值。这使得 EnumMap 的效率非常高。
public class EnumTest {
public static void main(String[] args) {
//EnumSet的使用
//把Signal枚举中所有对象抽取到Set集合中
EnumSet<Signal> signalSet = EnumSet.allOf(Signal.class);
for (Enum<Signal> en : signalSet) {
System.out.println(en);
}
//EnumMap的使用
EnumMap<Signal,Object> enumMap = new EnumMap<>(Signal.class);
enumMap.put(Signal.RED, "红灯");
enumMap.put(Signal.YELLOW, "黄灯");
enumMap.put(Signal.GREEN, "绿灯");
//把所有的映射关系对象抽取到Set集合中
Set<Entry<Signal, Object>> entrySet = enumMap.entrySet();
for (Entry<Signal, Object> entry : entrySet) {
Signal key = entry.getKey();
Object value = entry.getValue();
System.out.println(key + " -- " + value);
}
}
}
enum Signal{RED, YELLOW, GREEN}
类:
package com.qf.enumset_map;
public enum Color {
RED,GREEN,BLUE;
}
对象
package com.qf.enumset_map;
import java.util.EnumSet;
public class Test01 {
public static void main(String[] args) {
/**
* 知识点:EnumSet
*/
//将Color枚举类中所有的对象存入EnumSet集合中
EnumSet<Color> enumSet = EnumSet.allOf(Color.class);
for (Color color : enumSet) {
System.out.println(color);
}
}
}
对象
package com.qf.enumset_map;
import java.util.EnumMap;
import java.util.Map.Entry;
import java.util.Set;
public class Test02 {
public static void main(String[] args) {
/**
* 知识点:EnumMap
*/
//创建EnumMap的对象(注意:设置Key和value的类型)
EnumMap<Color,String> map = new EnumMap<>(Color.class);
//添加元素
map.put(Color.RED, "红色");
map.put(Color.GREEN, "绿色");
map.put(Color.BLUE, "蓝色");
//删除元素
map.remove(Color.GREEN);
//遍历
Set<Entry<Color, String>> entrySet = map.entrySet();
for (Entry<Color, String> entry : entrySet) {
Color key = entry.getKey();
String value = entry.getValue();
System.out.println(key + " -- " + value);
}
}
}
学生管理系统
Student.java
StuInfoUtils.java
IStudentManagerSystem.java
StudentManageSystemImpl.java
Main.java
StateCode.java
StuInfoType.java
初识集合
-
集合是Java API所提供的一系列类,可以用于动态存放多个对象 (集合只能存对象)(误导性太强,不去纠结)
-
集合与数组的不同在于,集合是大小可变的序列,而且元素类型可以不受限定,只要是引用类型。(集合中不能放基本数据类型,但可以放基本数据类型的包装类)
-
集合类全部支持泛型,是一种数据安全的用法。
-
集合与数组的不同
数组:一旦初始化后长度不可变,元素类型受限定(String类型的数组只能装String的数据),数组可以存储基本数据类型
集合:长度可变的序列,元素类型不受限定(一个集合可以存储多个数据类型的元素),集合只能存储引用数据类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KOLBBp31-1644159259793)(D:2113java_workspaceDay15Day15下午集合框架图.png)]
ArraryList
package com.dream.arraylist_class;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.ListIterator;
public class Test02 {
public static void main(String[] args) {
/**
* 知识点:ArrayList的方法
* ArrayList的底层数据结构就是一维数组,即ArrayList的底层数据存储到了一个一维数组里。
*/
//创建ArrayList对象
ArrayList<String> list = new ArrayList<>();
//添加元素
list.add("麻生希");
list.add("椎名空");
list.add("北岛玲");
list.add("朝桐光");
list.add("黄小龙");
//获取元素的个数
int size = list.size();
System.out.println("获取元素的个数:" + size);
//设置指定下标上的元素
list.set(2, "李尧尧");
//获取指定下标上的元素
String element = list.get(2);
System.out.println("获取指定下标上的元素:" + element);
//在指定下标上添加元素
list.add(1, "马锡彬");
//在list集合末尾添加newList1集合
ArrayList<String> newList1 = new ArrayList<>();
Collections.addAll(newList1, "aaa","bbb","ccc");//将元素批量添加到newList1中(注意:Collections-集合的工具类)
list.addAll(newList1);
//在list集合指定下标的位置添加newList2集合
ArrayList<String> newList2 = new ArrayList<>();
Collections.addAll(newList2, "xxx","yyy","zzz","黄小龙");
list.addAll(3, newList2);
//清空集合中的元素
//list.clear();
System.out.println("判断集合中是否有指定元素:" + list.contains("aaa"));
System.out.println("判断集合中是否有指定集合的元素(包含关系):" + list.containsAll(newList1));
System.out.println("判断集合中是否不包含元素:" + list.isEmpty());//true-没有元素 false-有元素
System.out.println("获取第一次出现的元素的下标:" + list.indexOf("黄小龙"));//6
System.out.println("获取最后一次出现的元素的下标:" + list.lastIndexOf("黄小龙"));//9
//删除元素
list.remove(2);//根据下标删除元素
list.remove("朝桐光");//根据元素删除元素
list.removeAll(newList1);//删除交集
//保留交集
list.retainAll(newList2);
//将集合转换为数组
Object[] array = list.toArray();
System.out.println(Arrays.toString(array));
System.out.println("-----------");
//遍历集合 -- for循环
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("-----------");
//遍历集合 -- foreach
for (String str : list) {
System.out.println(str);
}
System.out.println("-----------");
//遍历集合 -- Iterator
Iterator<String> it = list.iterator();
while(it.hasNext()){//判断是否有可迭代的元素
String next = it.next();//获取下一个元素
System.out.println(next);
}
System.out.println("-----------");
//遍历集合 -- ListIterator
ListIterator<String> listIt = list.listIterator();
while(listIt.hasNext()){//判断是否有可迭代的元素
String next = listIt.next();//获取下一个元素
System.out.println(next);
}
System.out.println("-----------");
}
}
加newList1集合
ArrayList newList1 = new ArrayList<>();
Collections.addAll(newList1, “aaa”,“bbb”,“ccc”);//将元素批量添加到newList1中(注意:Collections-集合的工具类)
list.addAll(newList1);
//在list集合指定下标的位置添加newList2集合
ArrayList<String> newList2 = new ArrayList<>();
Collections.addAll(newList2, "xxx","yyy","zzz","黄小龙");
list.addAll(3, newList2);
//清空集合中的元素
//list.clear();
System.out.println("判断集合中是否有指定元素:" + list.contains("aaa"));
System.out.println("判断集合中是否有指定集合的元素(包含关系):" + list.containsAll(newList1));
System.out.println("判断集合中是否不包含元素:" + list.isEmpty());//true-没有元素 false-有元素
System.out.println("获取第一次出现的元素的下标:" + list.indexOf("黄小龙"));//6
System.out.println("获取最后一次出现的元素的下标:" + list.lastIndexOf("黄小龙"));//9
//删除元素
list.remove(2);//根据下标删除元素
list.remove("朝桐光");//根据元素删除元素
list.removeAll(newList1);//删除交集
//保留交集
list.retainAll(newList2);
//将集合转换为数组
Object[] array = list.toArray();
System.out.println(Arrays.toString(array));
System.out.println("-----------");
//遍历集合 -- for循环
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("-----------");
//遍历集合 -- foreach
for (String str : list) {
System.out.println(str);
}
System.out.println("-----------");
//遍历集合 -- Iterator
Iterator<String> it = list.iterator();
while(it.hasNext()){//判断是否有可迭代的元素
String next = it.next();//获取下一个元素
System.out.println(next);
}
System.out.println("-----------");
//遍历集合 -- ListIterator
ListIterator<String> listIt = list.listIterator();
while(listIt.hasNext()){//判断是否有可迭代的元素
String next = listIt.next();//获取下一个元素
System.out.println(next);
}
System.out.println("-----------");
}
}
最后
以上就是淡淡樱桃为你收集整理的Week03Day11Day12Day13Day14Day15的全部内容,希望文章能够帮你解决Week03Day11Day12Day13Day14Day15所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复