Java学习路线12——日期、包装类、正则表达式、数组、常见算法和Lambda表达式
一、日期家族API
- Date
概念: Java提供的获取当前系统时间。
构造器:
构造器 | 说明 |
---|---|
public Date() | 创建默认Date对象 |
public Date(long time) | 创建指定时间戳的Date对象 |
常用方法:
方法 | 说明 |
---|---|
long getTime() | 获取当前系统时间戳 |
long setTime(long time) | 修改日期 |
创建方式:
Date date = new Date(); //创建Date对象
long time =d.getTime(); //获取毫秒级时间
- SimpleDateFormat
作用: 格式化时间对象成字符串,字符串解析时间。
构造器:
构造器 | 说明 |
---|---|
public SimpleDateFormat() | 创建默认格式化对象 |
public SimpleDateFormat(String pattern) | 按照一定规则创建格式化对象 |
常用方法:
方法 | 说明 |
---|---|
statuc final String format(Date date) | 格式化日期对象转为字符串 |
statuc final String format(Object time) | 格式化时间戳转为字符串 |
statuc Date parse(String source) | 时间字符串解析成日期对象 |
使用方式:
/*格式化时间*/
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss EEE a");
Date date = new Date();
System.out.println(sdf.format(date));
//打印结果
2023年05月25日 18:40:45 周四 下午
/*注意:时间字符串的格式要与格式化对象的格式化模式相同*/
String dateStr = "2023年05月25日 12:00:00" //时间字符串
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
Date date1 = sdf1.parse(dateStr); //解析
System.out.println(sdf.format(date1));
//打印结果
2023年05月25日 12:00:00 周四 下午
练习案例:
需求:
KFC活动,KFC全家桶一折优惠券,有两个客人抢购,分别在不同时间下单并付款。
客户要求: 判断是否超时活动。
解决方案:
public class Test {
//1、格式化对象创建
static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
//2、规定时间
static final long START_TIME;
static {
try {
START_TIME = sdf.parse("2023年05月01日 00:00:00").getTime();
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
static final long END_TIME;
static {
try {
END_TIME = sdf.parse("2023年05月01日 00:10:00").getTime();
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) throws ParseException {
//3、解析时间
long time1 = sdf.parse("2023年05月01日 00:03:47").getTime();
long time2 = sdf.parse("2023年05月01日 00:10:11").getTime();
//4、判断是否超时
if (checkTime(time1)) System.out.println("顾客1超时");
else System.out.println("顾客1未超时");
if (checkTime(time2)) System.out.println("顾客2超时");
else System.out.println("顾客2未超时");
}
public static boolean checkTime(long time){
return START_TIME >= time || END_TIME <= time;
}
- Calender
概念: 一个抽象类,代表系统此刻日期对应的日历对象。
创建方法
方法 | 说明 |
---|---|
static Calendar getInstance() | 获取当前日历对象 |
常用方法
方法 | 说明 |
---|---|
int get(int field) | 获取日期中某字段信息 |
void set(int field,int value) | 修改日期中某字段信息 |
void add(int field,int amount) | 为某个字段增减指定值 |
final Date getTime() | 获取当前日期对象 |
long getTimeInMillis() | 获取当前时间戳 |
代码演示
Calendar calendar = Calendar.getInstance();
System.out.println(calendar);
//打印结果
java.util.GregorianCalendar[time=1685013493488,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2023,MONTH=4,WEEK_OF_YEAR=21,WEEK_OF_MONTH=4,DAY_OF_MONTH=25,DAY_OF_YEAR=145,DAY_OF_WEEK=5,DAY_OF_WEEK_IN_MONTH=4,AM_PM=1,HOUR=7,HOUR_OF_DAY=19,MINUTE=18,SECOND=13,MILLISECOND=488,ZONE_OFFSET=28800000,DST_OFFSET=0]
- JDK8 新增日期类
所属包: java.time
类型
方法 | 说明 |
---|---|
LocalDate | 日期 |
LocalTime | 时间 |
LocalDateTime | 日期 时间 |
Instant | 时间戳 |
DateTimeFormatter | 格式化 |
Duration | 计算时间间隔 |
Period | 计算日期间隔 |
1、LocalDate、LocalTime、LocalDateTime
分别表示日期、时间、日期时间对象,实例是不可变对象。
构建对象方法
方法 | 说明 |
---|---|
static Xxxx now() | 根据当前时间创建对象 |
static Xxxx of(…) | 指定日期/时间对象 |
创建对象
- now()
LocalDate localDate = LocalDate.now();
LocalDate localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTime.now();
- of(…)
LocalDate localDate = LocalDate.of(1999,11,11);
LocalDate localTime = LocalTime.of(15,12,1);
LocalDateTime localDateTime = LocalDateTime.of(1999,11,11,15,12,1);
LocalDateTime转换LocalDate/LocalTime方法
方法 | 说明 |
---|---|
LocalDate toLocalDate() | 转换为LocalDate对象 |
LocalTime toLocalTime() | 转换为LocalTime对象 |
修改方法
方法 | 说明 |
---|---|
plusDays,plusWeeks,plusMonths,plusYears | 向当前日期对象添加 |
minusDays,minusWeeks,minusMonths,minusYears | 向当前日期对象减少 |
withDaysOfMonth,withDaysOfYear,withMonth,withYear | 将月份天数,年份天数,月份,年份修改并返回新的日期对象 |
isBefore,isAfter,equals | 比较日期对象 |
2、Instant时间戳
概念: JDK新加入的获取当前时间戳的工具类,通过静态工厂方法now()返回当前时间戳。
Instant is = Instant.now();
System.out.println(is);
//打印结果
2023-05-26T09:26:46.807932900Z
Date与Instant之间的相互转换
/*Instant时间戳*/
Instant instant = Instant.now();
System.out.println(instant);
/*Date时间戳,意思是从Instant中获取日期*/
Date date = Date.from(instant);
System.out.println(date);
/*Date->Instant,意思是从Date中获取Instant时间戳并转换格式*/
instant = date.toInstant();
System.out.println(instant);
//打印结果
2023-05-26T09:30:18.963385500Z
Fri May 26 17:30:18 CST 2023
2023-05-26T09:30:18.963Z
问:为什么Instant获取的时间并不是当前的时间?
答:因为Instant默认获取的是标准时间UTC,并不是本地时间。
如何获取当地时间?
Instant instant = Instant.now();
/*使用atZone()改变时区,ZoneId.systemDefault()获取当前系统时区*/
instant.atZone(ZoneId.systemDefault());
3、DateTimeFormat格式化对象
概念: 类似SimpleDateFormat的概念,不同的是DateTimeFormat主要是针对LocalXXX日期对象。
示例:
/*获取当前日期对象*/
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime);
/*创建格式化对象*/
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/*方式一:格式化对象解析日期对象*/
String date1 = dtf.format(localDateTime);
System.out.println(date1);
/*方式二:日期对象通过格式化对象解析*/
String date2 = localDateTime.format(dtf);
System.out.println(date2);
/*解析字符串*/
String dateStr = "2021-01-01 12:00:00";
localDateTime = LocalDateTime.parse(dateStr,dtf);
System.out.println(localDateTime);
/*打印结果*/
2023-05-26T17:46:52.894691400
2023-05-26 17:46:52
2023-05-26 17:46:52
2021-01-01T12:00
4、Period
作用: 用于计算两个日期之间的间隔。
示例:
/*获取当前日期*/
LocalDate today = LocalDate.now();
System.out.println(today);
/*获取指定日期*/
LocalDate birthday = LocalDate.of(1999,10,23);
System.out.println(birthday);
/*创建间隔对象*/
Period period = Period.between(birthday,today); //between(sourceDate,minusDate)
System.out.println(period.getYears());
System.out.println(period.getMonths());
System.out.println(period.getDays());
/*打印结果*/
2023-05-26
1999-10-23
23
7
3
5、Duration
作用: 用于计算两个日期之间之差。
示例:
/*获取当前日期*/
LocalDateTime today = LocalDateTime.now();
System.out.println(today);
/*获取指定日期*/
LocalDateTime birthday = LocalDateTime.of(1999,10,23,20,0,0);
System.out.println(birthday);
/*创建间隔对象*/
Duration duration = Duration.between(birthday,today); //between(maxDate,minDate)
System.out.println(duration.toDays());
System.out.println(duration.toHours());
System.out.println(duration.toSeconds());
/*打印结果*/
2023-05-26T18:16:22.533343100
1999-10-23T20:00
8615
206782
744416182
二、包装类
概念: 基本数据类型对应的引用类型。
种类
基本数据类型 | 引用数据类型 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
char | Charactor |
float | Float |
double | Double |
boolean | Boolean |
装箱与拆箱
Java提供的包装类可以自动装箱与自动拆箱。
- 自动装箱: 基本数据类型和变量可以直接赋值给包装类型的变量。
- 自动拆箱: 包装类型的变量可以直接赋值给基本数据类型的变量。
int a = 10;
Integer a1 = a; //自动装箱
int b = a1; //自动拆箱
特有功能
- 包装类的变量默认为null
- 将基本数据类型数据转为String
- 1、toString()转为String对象。
- 2、Integer.toString(基本类型数据)。
- 将String类型的数值转为对应数据类型
- 1、Integer parseInt(String str)
- 2、Double parseDouble(String str)
三、正则表达式
作用: 规定一些字符制定校验规则。
正则表达式中的字符标准
1、字符类(默认匹配一个字符)
字符 | 说明 |
---|---|
[abc] | 只能是a,b,c |
[^abc] | 不能能是a,b,c |
[a-zA-Z] | a到z和A到Z的范围 |
[a-z&&[def]] | a到z范围内与d,e,f发生交集的字符 |
2、预定义的字符类(默认匹配一个字符)
字符 | 说明 |
---|---|
. | 任意字符 |
\d | 一个数字 |
\D | 非数字 |
\s | 一个空白字符,包含【\t\n\x0B\f\r】 |
\S | 非空白字符 |
\w | 英文,数字,下划线 |
\W | 一个非单词字符 |
3、贪婪量词(匹配多个字符)
字符 | 说明 |
---|---|
X? | 匹配X 0次或1次 |
X* | 匹配X 0次或多次 |
X | 匹配X 1次或多次 |
X{n} | 匹配X n次 |
X{n,} | 匹配X 至少n次 |
X{n,m} | 匹配X 至少n次但不超过m次 |
使用正则表达式校验
/*校验方法*/
public boolean matches(String regex)
/*使用*/
"a".matches("\w"); // true
"&".matches("\w"); // false
校验案例:
/*校验手机号(简易版)*/
public static boolean checkPhone(String phone){
if(phone.matches("1[3-9]\\d{9}")) return true;
return false;
}
/*校验邮箱(简易版)*/
public static boolean checkMail(String mail){
if(mail.matches("\\w{1,30}@[a-zA-Z0-9]{2,20}(\\.[a-zA-Z0-9]{1,2})")) return false;
return false;
}
正则表达式爬取信息
String sourceData = "数据源";
/*1、定义爬取规则*/
String regex = "校验规则";
/*2、编译正则表达式为一个匹配规则对象Pattern*/
Pattern pattern = Pattern.compile(regex);
/*3、创建匹配器*/
Matcher matcher = pattern.matcher(sourceData);
/*4、获取信息*/
while(matcher.find()){
System.out.println(matcher.gourp());
}
四、Arrays数组类
概念: 专门用于操作数组元素的工具类。
常用API
方法 | 说明 |
---|---|
static String toString(类型[] a) | 数组转字符串 |
static void sort(类型[] a) | 数组排序(默认升序) |
static void sort(类型[] a,Comparator <? super T> c) | 使用自定义比较器排序 |
static int binarySearch(类型[] a,int key) | 二分查找数据,存在返回索引,不存在返回-1 |
使用案例:
/*1、定义数组*/
int[] arr = new int[]{3,5,7,2,4,7};
System.out.println(Arrays.toString(arr));
/*2、排序*/
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
/*3、二分查找(必须先排序)*/
System.out.println(Arrays.binarySearch(arr, 5));
System.out.println(Arrays.binarySearch(arr, 0));
/*打印结果*/
[3, 5, 7, 2, 4, 7]
[2, 3, 4, 5, 7, 7]
3
-1
/*比较器排序*/
Arrays.sort(arr,new Comparator<Integer>(){
@Override
public int compare(Integer o1,Integer o2){
/*比较规则:左边>右边则为正,左边<右边则为负,相等则为0*/
return o1-o2;
}
})
注意: 比较器主要用于对象之间的排序。
五、常见算法:选择排序与折半查找
- 选择排序
选择排序原则是将符合规则的元素替换至当前位置。
public static void main(String[] args){
chooseSort(new int[]{3,1,2,4,8});
}
/*该方法为降序排序,若想要降序,则通过改变比较方法进行降序*/
private static void chooseSort(int[] arr) {
/*控制循环轮数也指向当前位置,所有数的排序需要经历n-1轮才能完成*/
/*升序*/
for(int i = 0;i < arr.length-1;i ){
/*控制比较次数,一个数的排序需要经历n-i次比较*/
for(int j = i; j < arr.length-1;j ){
if(arr[j 1] > arr[i]){
int temp = arr[j 1];
arr[j 1] = arr[i];
arr[i] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
/*升序*/
for(int i = 0;i < arr.length-1;i ){
/*控制比较次数,一个数的排序需要经历n-i次比较*/
for(int j = i; j < arr.length-1;j ){
if(arr[j 1] < arr[i]){
int temp = arr[j 1];
arr[j 1] = arr[i];
arr[i] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
/*打印结果*/
[8, 4, 3, 2, 1]
[1, 2, 3, 4, 8]
- 折半查找
折半查找是在排序后的结果进行查找,其高效性主要体现在折半。
原则: 分别设立头尾两个指针,每次查找都要设立新的中立点,通过中立点的值比较查找值,若中立点与查询值差值为负,则中立点<查询值,尾指针移动到中立点,并重新设立中立点;若中立点与查询值差值为正,则中立点>查询值,头指针移动到中立点,并重新设立中立点;当差值为0,则查找到了索引。当头尾指针交错时,则查找不到,返回-1(因为索引没有负值)。
public static void main(String[] args){
System.out.println(binarySearch(new int[]{3, 1, 2, 4, 8}, new Scanner(System.in).nextInt()));
}
/*折半查找*/
private static int binarySearch(int[] arr,int key){
/*避免传入空数组*/
if (arr.length > 0){
/*避免没有排序*/
chooseSort(arr);
/*判断是否在数组区间内*/
if ((key <= arr[arr.length-1] && key >= arr[0]) || (key >= arr[arr.length-1] && key <= arr[0])){
/*设立头尾中指针*/
int start = 0,end = arr.length-1;
while(start <= end){
int mid = (start end)/2;
if (arr[mid] == key){
return mid;
}
if (key < arr[mid]){
end = mid;
}
if (key > arr[mid]){
start = mid;
}
}
}
}
/*未查找到*/
return -1;
}
/*打印结果*/
数组:[1,2,3,4,8]
输入:1
输出:0
输入:3
输出:2
输入:11
输出:-1
六、Lambda
概念: 它是JDK8开始后的新语法形式。
作用: 简化匿名内部类的代码写法。
格式:
(形参列表) -> {
重写方法体
}
省略原则:
1、参数类型可以省略不写
2、如果只有一个参数,则使用【x -> {方法体}】格式
3、如果方法体只有一行代码则使用【x -> 方法体】格式
4、如果只有一行代码且为return语句,则省略return与;直接使用返回值。
public class Main {
public static void main(String[] args){
/* 简化究极版本*/
run(content -> content "冲线了");
}
public static void run(Run run){
System.out.println("各就位,预备,开始···");
System.out.println(run.run("xxx"));
System.out.println("我们是冠军···");
}
}
@FunctionalInterface
interface Run{
String run(String xxx);
}
注意: Lambda表达式只能简化函数式接口(即只有一个抽象方法的接口)。
如何限制一个接口为函数式接口: 使用**@FunctionalInterface**注释即可。
问:为什么一定是函数式接口才能被简化?
答:因为函数式接口只有一个抽象方法,Lambda也只能重写一个方法,所以它们一拍即合,你不用给我完整的代码规范,我就知道你要重写什么方法。
示例:
class Main{
public static void main(String[] args){
/*正常写法*/
/*这里的new 接口名()是匿名类的一种写法,并不是实例化请注意*/
Run run = new Run(){
@Override
public void run(){
System.out.println("跑得很快,冲线了。");
}
};
run(run);
/*Lambda简化写法*/
run(()->{System.out.println("跑得很快,冲线了。");});
}
public static void run(Run run){
System.out.println("各就位,预备,开始···");
run.run();
System.out.println("我们是冠军···");
}
}
@FunctionalInterface
interface Run{
void run();
}
/*打印结果*/
各就位,预备,开始···
P1跑得很快,冲线了。
我们是冠军···
各就位,预备,开始···
P2跑得很快,冲线了。
我们是冠军···
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgffchf
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01