第十二章 常用API、Lambda、常见算法
前言
一、日期与时间
Date
Date类概述
- Date类的对象在Java中代表的时当前所在系统的此刻日期时间。
Date的构造器
Date的常用方法
Date类记录时间的2种形式
形式1:日期对象
形式2:时间毫秒值
- 指的是从1970年1月1日 00:00:00r走到此刻的总的毫秒数,应该是很大的
案例 - 请计算出当前时间往后走1小时121秒之后的时间是多少。
时间毫秒值 -> 日期对象
import java.util.Date;
/**
目标:学会使用Date类处理时间,获取时间的信息
*/
public class DateDemo1 {
public static void main(String[] args) {
//1、创建一个Date类的对象,代表系统此刻日期时间对象
Date d = new Date();
System.out.println(d);
//2、获取时间毫秒值
long time = d.getTime();
System.out.println(time);
// long time1 = System.currentTimeMillis();
// System.out.println(time1);
System.out.println("------------------");
//1、得到当前时间毫秒值
Date d1 = new Date();
System.out.println(d1);
//2、当前时间往后走 1小时 121秒
long time2 = System.currentTimeMillis();
time2 += (60 * 60 + 121) * 1000;
//1、吧时间毫秒值转换成对应的日期对象
Date d2 = new Date(time2);
System.out.println(d2);
Date d3 = new Date();
d3.setTime(time2);
System.out.println(d3);
}
}
SimpleDateFormat
SimpleDateFormat类作用
- 可以对Date对象或时间毫秒值格式化成我们喜欢的时间模式。
- 也可以把字符串的时间形式解析成日期对象。
时间形式一:日期类表示时间的代码:
时间形式二:时间毫秒值表示时间的代码:
开发中常见的时间形式
SimpleDateFormat的构造器
SimpleDateFormat的格式化方法
格式化的时间形式的常用模式对应关系如下:
SimpleDateFormat解析字符串时间成为日期对象
案例 - 请计算出2022年05月13日11点11分11秒,往后走2天14小时49分06秒后的时间是多少。
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SimpleDateFormatDemo2 {
public static void main(String[] args) throws ParseException {
//目标:学会使用SimpleDateFormat解析字符串时间成为日期对象。
//有一个时间 2022年05月13日 11:11:11 往后走2天14小时49分06秒后的时间是多少
//1、把字符串时间拿到程序中来
String dateStr = "2022年05月13日 11:11:11";
//2、把字符串时间解析成日期对象(本节重点):形式必须与被解析时间的形式完全一致,否则运行时解析报错!
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
Date d = sdf.parse(dateStr);
//3、往后走2天14小时49分06秒
long time = d.getTime() + (2L*24*60*60 + 14*60*60 + 49*60 + 6) * 1000;
//4、格式化这个时间毫秒值就是结果
System.out.println(sdf.format(time));
}
}
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SimpleDateFormatTest3 {
public static void main(String[] args) throws ParseException {
//1、开始 和 结束时间
String startTime = "2022-5-14 00:00:00";
String endTime = "2022-5-14 00:10:00";
//2、小贾 小皮
String XiaoJia = "2022-5-14 00:03:47";
String XiaoPi = "2022-5-14 00:10:11";
//3、解析他们的时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d1 = sdf.parse(startTime);
Date d2 = sdf.parse(endTime);
Date d3 = sdf.parse(XiaoJia);
Date d4 = sdf.parse(XiaoPi);
if (d3.after(d1) && d3.before(d2)){
System.out.println("小贾秒杀成功,可以发货了!");
}else {
System.out.println("小贾秒杀失败!!");
}
if (d4.after(d1) && d4.before(d2)){
System.out.println("小皮秒杀成功,可以发货了!");
}else {
System.out.println("小皮秒杀失败!!");
}
}
}
Calendar
Calendar概述
- Calendar代表了系统此刻日期对应的日历时间。
- Calendar是一个抽象类,不能直接创建对象。
Calendar常用方法
注意:calendar是可变日期对象,一旦修改后其对象本身表示的时间将产生变化。
二、JDK8新增日期类
1、概述、LocalTime / LocalDate / LocalDateTime
概述
- 从Java 8 开始,java.time包提供了新的日期和时间API,主要涉及的类型有:
- 新增的API严格区分了时刻、本地日期、本地时间,并且,对日期和时间进行运算更加方便。
- 其次,新API的类型几乎全都是不变类型(和String的使用类似),可以放心使用不必担心被修改。
LocalDate、LocalTime、LocalDateTime
- 它们分别表示日期,时间,日期时间对象,他们的类的实例是不可变的对象。
- 他们三者构建对象和API都是通用的。
构建对象的方式如下:
LocalDate、LocalTime、LocalDateTime获取信息的API
修改相关的API
- LocalDateTime 综合了 LocalDate 和 LocalTime 里面的方法,所以下面只用 LocalDate 和 LocalTime 来举例。
- 这些方法返回的是一个新的实例引用,因为LocalDateTime、LocalDate、LocalTime 都是不可变的。
2、Instant
Instant时间戳
- JDK8获取时间戳特别简单,且功能丰富。Instant类由一个静态的工厂方法now()可以返回当前时间戳。
- 时间戳是包含日期和时间的,与java.util.Date很类似,事实上Instant就是类似JDK8以前的Date。
- Instant和Date这两个类可以进行转换。
3、DateTimeFormatter
DateTimeFormatter
- 在JDK8中,引入了一个全新的日期与时间格式器DateTimeFormatter。
- 正反都能调用format方法。
4、Duration / Period
Period
- 在Java8中,我们可以使用以下类来计算日期间隔差异:java.time.Period
- 主要是Period类方法getYears(),getMonths() 和 getDays() 来计算,只能精确到年月日。
- 用于LocalDate 之间的比较。
Duration
- 在Java8中,我们可以使用以下类来计算时间间隔差异:java.time.Duration
- 提供了使用基于时间的值测量时间量的方法。
- 用于LocalDateTime 之间的比较。也可用于Instant 之间的比较。
5、ChronoUnit
java.time.temporal.ChronoUnit
- ChronoUnit类可用于在单个时间单位内测量一段时间,这个工具类是最全的了,可以用于比较所有的时间单位。
三、包装类
包装类
- 其实就是8种基本数据类型对应的引用类型。
为什么提供包装类?
- Java为了实现一切皆对象,为8种基本类型对应的引用类型。
- 后面的集合和泛型其实也只能支持包装类型,不支持基本数据类型。
自动装箱:基本类型的数据和变量可以直接赋值给包装类型的变量。
自动拆箱:包装类型的变量可以直接赋值给基本数据类型的变量。
包装类的特有功能
- 包装类的变量的默认值可以是null,容错率更高。
- 可以把基本类型的数据转换成字符串类型(用处不大)
- 可以把字符串类型的数值转换成真实的数据类型(真的很有用)
四、正则表达式
1、正则表达式概述、初体验
正则表示
- 正则表达式可以用一些规定的字符来制定规则,并用来校验数据格式的合法性。
正则表达式初体验
- 需求:假如现在要求校验一个qq号码是否正确,6位及20位之内,必须全部是数字。
- 现在使用目前所学知识完成校验需求;然后体验一下正则表达式检验。
2、正则表达式的匹配规则
字符类(默认匹配一个字符)
预定义的字符类(默认匹配一个字符)
贪婪的量词(配合匹配多个字符)
字符串对象提供了pipei-正则表达式规则的API
public boolean matches(String regex):判断是否匹配正则表达式,匹配返回true,不匹配返回false。
3、正则表达式的常见案例
import java.util.Scanner;
public class RegexDemo03 {
public static void main(String[] args) {
//目标:校验 手机号码 邮箱 电话号码
//checkPhone();
//checkEmail();
checkTel();
//校验金额格式:99 0.5 99.5 018 错误:0.8.9
}
public static void checkTel(){
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请您输入您的电话号码:");
String tel = sc.next();
//判断电话号码的格式是否正确 029-2681268 0292681268
if (tel.matches("0\\d{2,6}-?\\d{5,20}")){
System.out.println("电话号码格式正确,注册完成!");
break;
}else {
System.out.println("格式有误!");
}
}
}
public static void checkEmail(){
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请您输入您注册的邮箱:");
String email = sc.next();
//判断邮箱的格式是否正确 37483692.@qq.com
//判断邮箱的格式是否正确 37483hcug692.@163.com
//判断邮箱的格式是否正确 37483692.@pci.com.cn
if (email.matches("\\w{1,30}@[a-zA-z0-9]{2,20}(\\.[a-zA-z0-9]{2,10}){1,2}")){
System.out.println("邮箱格式正确,注册完成!");
break;
}else {
System.out.println("格式有误!");
}
}
}
public static void checkPhone(){
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请您输入您注册的手机号:");
String phone = sc.next();
//判断手机号码的格式是否正确
if (phone.matches("1[3-9]\\d{9}")){
System.out.println("手机号码格式正确,注册完成!");
break;
}else {
System.out.println("格式有误!");
}
}
}
}
4、正则表达式在方法中的应用
正则表达式在字符串方法中的使用
5、正则表达式爬取信息
五、Arrays类
1、Arrays类概述,常用功能演示
Arrays类概述
- 数组操作工具类,专门用于操作数组元素的。
Arrays类的常用API
2、Arrays类对于Comparator比较器的支持
Arrays类的排序方法
自定义排序规则
- 设置Comparator接口对应的比较器对象,来定制比较规则。
六、常见算法
1、选择排序
选择排序的思想
- 每轮选择当前位置,开始找出后面的较小值与该位置交换。
选择排序的关键
- 确定总共需要选择几轮:数组的长度-1.
- 控制每轮从以前位置为基准,与后面元素选择几次。
2、二分查找
基本查找
结论:在数据量特别大的时候,基本查找从前往后寻找的性能是很差的!
二分查找
- 二分查询性能好,二分查找的前提是必须是排好序的数据。
- 二分查找相当于每次去掉一半的查找范围
二分查找 -------元素不存在
结论:二分查找正常的检索条件应该是开始位置min <= 结束位置max
七、Lambda表达式枚举
1、Lambda概述
Lambda概述
- Lambda表达式是JDK 8开始后的一种新语法形式。
- 作用:简化匿名内部类的代码写法。
Lambda表达式的简化格式
注意:Lambda表达式只能简化函数式接口的匿名内部类的写法形式
什么是函数式接口?
- 首先必须是接口、其次接口中有且仅有一个抽象方法的形式
- 通常我们会在接口上加上一个@FunctionalInterface注解,标记该接口必须是满足函数式接口。
2、Lambda实战-简化常见函数式接口
Lambda表达式简化Comparator接口的匿名形式
Lambda表达式简化按钮监听器ActionListener的匿名内部类形式
3、Lambda表达式的省略规则
Lambda表达式的省略写法(进一步在Lambda表达式的基础上继续简化)
- 参数类型可以省略不写。
- 如果只有一个参数,参数类型可以省略,同时()也可以省略。
- 如果Lambda表达式的方法体代码只有一行代码。可以省略大括号不写,同时要省略分号!
- 如果Lambda表达式的方法体代码只有一行代码。可以省略大括号不写。此时,如果这行代码是return语句,必须省略return不写,同时也必须省略";"不写