• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Java学习路线12——日期、包装类、正则表达式、数组、常见算法和Lambda表达式

武飞扬头像
Zain_horse
帮助1

一、日期家族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
系列文章
更多 icon
同类精品
更多 icon
继续加载