1.日期与时间

1.1、Date

  • Date类概述
    • Date类代表当前所在系统的日期时间信息
  • Date的构造器 image-20230810160300707.png
  • Date的常用方法 image-20230810160308331.png

  • 案例:请计算出当前时间往后走1小时121秒之后的时间是多少

public class Test {
    public static void main(String[] args) {
        //计算当前时间过1个小时121秒后的时间
        //方式一:获取当前时间
        //long currentTime = new Date().getTime();
        //方式二:
        long currentTime = System.currentTimeMillis();

        //计算时间后1小时121秒后的时间
        long time = currentTime+(60*60+121)*1000;

        //吧时间毫秒值换为日期形式
        System.out.println(new Date(time));
    }
}

1.2、SimpleDateFormat

代表简单日期格式化,可以用来吧日期时间格式化成想要的形式

  • 构造器

image-20230810160317978.png

  • 格式化方法

image-20230810160325424.png

  • 格式化的时间形式的常用模式对应关系

image-20230810160331751.png

  • 解析字符串时间称为日期对象

image-20230810160338320.png

public class Demo2 {
    public static void main(String[] args) throws Exception{
        String strDate = "2021-08-06 11:11:11";
        //规定格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //将字符串时间转化为Date形式
        Date date = sdf.parse(strDate);
        //输出字符串时间,并转为可观形式
        System.out.println(sdf.format(date));
        //计算之后增加时间   2天14小时40分6秒
        long time = date.getTime()+(62*60*60+ 49*60+6)*1000;
        //转为可观形式
        System.out.println(sdf.format(time));
    }
}

【案例】

某购物网站举办秒杀活动,开始时间和结束时间如左图所示,当前活动结束后,系统记录到2位用户的付款时间分别如下:

  1. 小贾下单并付款的时间为:2020年11月11日 0:03:47
  2. 小皮下单并付款的时间为:2020年11月11日 0:10:11

【规则】:顾客的付款时间必须在秒杀时间之内,请判断出两位顾客是否秒杀成功

image-20230810160346361.png

public class Demo3 {
    public static void main(String[] args) throws Exception{
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //秒杀开始时间
        Date start = sdf.parse("2020-11-11 00:00:00");
        //秒杀结束时间
        Date end = sdf.parse("2020-11-11 00:10:00");

        //小贾下单并付款时间
        Date jiaPayTime = sdf.parse("2020-11-11 00:03:47");
        //小皮下单并付款时间
        Date piPayTime = sdf.parse("2020-11-11 00:10:11");
        //判断小贾是否参与上活动
        if(jiaPayTime.after(start) && jiaPayTime.before(end)){
            System.out.println("小贾参与上了");
        }else {
            System.out.println("小贾未能抢到活动");
        }
        //判断小皮
        if(piPayTime.after(start) && piPayTime.before(end)){
            System.out.println("小皮参与上了");
        }else {
            System.out.println("小皮未能抢到活动");
        }
    }
}

1.3、Calendar

  • 概述
    • Calendar 代表了系统此刻日期对应的日历对象
    • Calendar 是一个抽象类,不能直接创建对象
  • Calendar日历对象创建的方法

image-20230810160356493.png

  • Calendar常用方法

image-20230810160403950.png

【注意】:Calendar是可变日期对象,一旦修改后其对象本身表示的时间将产生变化

public class Demo4 {
    public static void main(String[] args) {
        Calendar cal = Calendar.getInstance();
        //1.拿到系统此时日历信息
        System.out.println(cal);
        //2.获取日历信息,日期中的某一个(年,月,日)
        System.out.println(cal.get(Calendar.YEAR));
        System.out.println(cal.get(Calendar.MONTH));
        System.out.println(cal.get(Calendar.DAY_OF_YEAR));
        //3.修改日历的某个字段信息(不经常用,因为修改一个,之后的时间信息都有所变化)
        //cal.set(Calendar.MONTH,10);

        //4.为某个字段增加/减少指定时间值
        //cal.add(Calendar.MONTH,10);小时增加10

        //5.拿到此时日期对象
        Date date = cal.getTime();
        System.out.println(date);

        //6.拿到此时毫秒值(不经常用,方法很多)
        System.out.println(cal.getTimeInMillis());
    }

2.JDK8新增日期类

2.1、LocalTime/LocalDate/LocalDateTime

  • 概述

    • 从Java 8开始,java.time包提供了信的日期和时间API
    • 新增的API严格区分了时刻、本地日期、本地时间,并且,对日期和时间进行运算更加方便
    • 新API的类型几乎全部都是不变类型(和String的使用类似),可以放心使用不必担心被修改
  • LocalDate、LocalTime、LocalDateTime

    • 他们分别表示日期,时间,日期时间对象,他们的类实例是不可变对象
    • 三者构建对象API通用

image-20230810160414098.png

  • LocalDate

image-20230810160422677.png

  • LocalTime

image-20230810160428941.png

  • LocalDateTime转换API

image-20230810160434054.png

这些方法返回的是一个新的实例引用,因为LocalDateTime、LocalDate、LocalTime都是不可变的

  • LocalDateDemo
public class LocalDateDemo {
    public static void main(String[] args) {
        LocalDate localDate = LocalDate.now();
        //目前的时间
        System.out.println(localDate);
        //年
        System.out.println(localDate.getYear());
        //月
        System.out.println(localDate.getMonthValue());
        System.out.println(localDate.getMonth().getValue());
        //本年第几天
        System.out.println(localDate.getDayOfYear());
        //本月第几天
        System.out.println(localDate.getDayOfMonth());
        //周几
        System.out.println(localDate.getDayOfWeek().getValue());
        //手动填入日期
        LocalDate setTime = LocalDate.of(2001, 03, 02);
        System.out.println(setTime);
        //枚举参数
        LocalDate enumTime = LocalDate.of(2001, Month.MARCH, 2);
        System.out.println(enumTime);
    }
}
  • LocalTimeDemo
public class LocalTime_update {
    public static void main(String[] args) {
        LocalTime localTime = LocalTime.now();
        //当前时间
        System.out.println(localTime);
        //一小时之前
        System.out.println(localTime.minusHours(1));
        //一分钟之前
        System.out.println(localTime.minusMinutes(1));
        //一秒之前
        System.out.println(localTime.minusSeconds(1));
        System.out.println("--------------");
        //一小时之后
        System.out.println(localTime.plusHours(1));
        //一分钟之后
        System.out.println(localTime.plusMinutes(1));
        //一秒之后
        System.out.println(localTime.plusSeconds(1));
        System.out.println("----------------");
        //判断今天是2018-09-06么
        LocalDate setTime = LocalDate.of(2018, 9, 5);
        System.out.println("今天是2018.9.5吗?——————"+setTime.equals(setTime));
        //判断2018-09-05是否在2021-08-05之前
        LocalDate myTime = LocalDate.of(2021, 8, 5);
        System.out.println("2018-09-05是否在2021-08-05之前?——————"+myTime.isBefore(setTime));
        //判断2018-09-05是否在2021-08-05之后
        System.out.println("2018-09-05是否在2021-08-05之后?——————"+myTime.isAfter(setTime));
        System.out.println("-----------");
        //判断今天是自己的生日吗
        LocalDate birthDay = LocalDate.of(2001, 9, 28);
        MonthDay birMD = MonthDay.of(birthDay.getMonthValue(), birthDay.getDayOfMonth());//生日日期
        //当前日期,转为MonthDay
        LocalDate now = LocalDate.now();
        MonthDay nowMD = MonthDay.from(now);
        System.out.println("今天是自己的生日吗?——————"+birMD.equals(nowMD));
    }
}

2.2、Instant

  • Instant时间戳
    • JDK8获取时间戳比较简单,且功能更丰富。Instant类有
    • 时间戳是包含日期和时间的,与java.util.Date很类似,事实上Instant就是类似JDK8以前的Date
    • Instant和Date两类可以进行转换
public class InstantDemo {
    public static void main(String[] args) {
        //获取时间戳对象
        Instant instant = Instant.now();
        System.out.println(instant);
        //时间戳不对,正确处理修改系统正确时间
        System.out.println(instant.atZone(ZoneId.systemDefault()));
        //返回Date对象
        Date date = Date.from(instant);
        System.out.println(date);
    }
}

2.3、DateTimeFormatter

  • 概述
    • JDK8中,引入了一个全新的日期与时间各式器DateTimeFormatter
    • 正反都能调用format方法
public class DateTimeFormatterDemo {
    public static void main(String[] args) {
        //获取此刻时间对象
        LocalDateTime ldt = LocalDateTime.now();
        System.out.println(ldt);
        //解析格式化器
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        //正向格式化
        System.out.println(dtf.format(ldt));
        //逆向格式化
        System.out.println(ldt.format(dtf));
        //解析字符串时间
        String strDate = "2001-03-02 13:14:52";
        //解析当前字符串为本地日期时间对象
        LocalDateTime analysisTime = LocalDateTime.parse(strDate, dtf);
        System.out.println(analysisTime);
    }
}

2.4、Duration/Period

  • Period
    • 在JDK8中,我们可以使用这个类来计算日期间隔差异:java.time.Period
    • 主要是Period类方法 getYears(),getMonths()和getDays()来计算,只能精确到年月日
    • 用于LocalDate之间的比较
public class PeriodDemo {
    public static void main(String[] args) {
        //获取本地年月日
        LocalDate localDate = LocalDate.now();
        System.out.println(localDate);
        //设置生日的年月日
        LocalDate birthDay = LocalDate.of(2001, 3, 2);
        //计算之间相隔的时间,并获取对象返回值
        Period period = Period.between(birthDay, localDate);//第二个参数减去第一个参数
        //获取多余的年
        System.out.println("相隔多的年数:"+period.getYears());
        System.out.println("相隔多的月数:"+period.getMonths());
        System.out.println("相隔多的天数:"+period.getDays());
    }
}
  • Duration
    • Duration用来计算时间间隔差异:java.time.Duration
    • 提供了使用基于时间的值测量时间的方法
    • 用于LocalDateTime之间的比较。也可以用于Instant之间的比较
LocalDateTime today = LocalDateTime.now();
System.out.println(today);
LocalDateTime birthDate = LocalDateTime.of(1990,10,1,10,50,30);
System.out.println(birthDate);
Duration duration = Duration.between(birthDate, today);//第二个参数减第一个参数System.out.println(duration.toDays());//两个时间差的天数System.out.println(duration.toHours());//两个时间差的小时数System.out.println(duration.toMinutes());//两个时间差的分钟数System.out.println(duration.toMillis());//两个时间差的毫秒数System.out.println(duration.toNanos());//两个时间差的纳秒数

2.5、ChronoUnit

ChronoUnit可用在单个时间单位内测量一段时间,这个工具类最为全面,可以用于比较所有时间单位

public class ChronoUnitDemo {
    public static void main(String[] args) {
        //获取当前日期时间对象
        LocalDateTime ldt = LocalDateTime.now();
        //获取生日时间
        LocalDateTime birthDay = LocalDateTime.of(2001, 3, 2, 3, 30, 6);
        //使用Chrono算出时差
        System.out.println("相差的年:"+ChronoUnit.YEARS.between(birthDay,ldt));
        System.out.println("相差的月:"+ChronoUnit.MONTHS.between(birthDay,ldt));
        System.out.println("相差的周:"+ChronoUnit.WEEKS.between(birthDay,ldt));
        System.out.println("相差的日:"+ChronoUnit.DAYS.between(birthDay,ldt));
        System.out.println("相差的时:"+ChronoUnit.MONTHS.between(birthDay,ldt));
        System.out.println("相差的分:"+ChronoUnit.MINUTES.between(birthDay,ldt));
        System.out.println("相差的秒:"+ChronoUnit.SECONDS.between(birthDay,ldt));
        System.out.println("相差的毫秒:"+ChronoUnit.MILLIS.between(birthDay,ldt));
        System.out.println("相差的纳秒:"+ChronoUnit.NANOS.between(birthDay,ldt));
        System.out.println("相差的微秒:"+ChronoUnit.MICROS.between(birthDay,ldt));
        System.out.println("相差的半天数:"+ChronoUnit.HALF_DAYS.between(birthDay,ldt));
        System.out.println("相差的十年数:"+ChronoUnit.DECADES.between(birthDay,ldt));
        System.out.println("相差的世纪数:"+ChronoUnit.CENTURIES.between(birthDay,ldt));
    }
}

3.包装类

  • 概述
    • 8种基本数据类型对应的引用类型

image-20230810160453646.png

  • 为什么提供包装类

    • Java为了实现一切皆对象,为8种基本类型提供了对应的引用类型
    • 后面的集合和泛型只能支持包装类型,不支持基本数据类型
  • 自动装箱

    • 基本类型的数据和变量可以直接赋值给包装类型的变量
  • 自动拆箱

    • 包装类型的变量可以直接赋值给基本数据类型的变量
  • 包装类的特有功能

    • 包装类的变量值默认值可以是 null,容错率更高

    • 可以把基本类型的数据转换成字符串类型【了解】

image-20230810160501519.png

  • 可以把字符串类型的数值转换成真实的数据类型【实用】

image-20230810160509709.png

4.正则表达式

4.1、正则表达式概述、初体验

  • 表示
    • 正则表达式可以用一些规定的字符来指定规则,并用来校验数据格式的合法性
  • 初体验
    • 需求:加入现在需要要求校验一个QQ号码是否正确,6位及20位以内,全为数字

image-20230810160524883.png

public class Demo1 {
    public static void main(String[] args) {
        //校验QQ号,长度6-20,且全为数字
        System.out.println("1234jjj".matches("\\d{6,20}"));//fasle
        System.out.println("1274414446".matches("\\d{6,20}"));//true
        //匹配单个字符
        System.out.println("------------------");
        //数字
        System.out.println("3".matches("\\d"));
        System.out.println("j".matches("\\d"));
        //字符
        System.out.println("a".matches("[abc]"));//只要含a,b,c其中一个即可——true
        System.out.println("b".matches("[a-zA-Z]"));//只要是字母即可——true
        System.out.println("11".matches("\\w"));//false
        System.out.println("m".matches("\\w"));//true
        System.out.println("我".matches("\\w"));//false
        System.out.println("我".matches("\\W"));//true
        System.out.println("-----------");
        //校验密码,必须是数字,字母,下划线,至少六位
        System.out.println("555sss_2".matches("\\w{6,}"));//true
        System.out.println("555sss12".matches("\\w{6,}"));//true
        System.out.println("11".matches("\\w{6,}"));//false
        //校验验证码:必须是数字和字符,必须是四位
        System.out.println("123j".matches("[a-zA-Z0-9]{4}"));//true
        System.out.println("123_".matches("[a-zA-Z0-9]{4}"));//false
        System.out.println("222a".matches("[\\w&&[^_]]{4}"));//true
        System.out.println("222_".matches("[\\w&&[^_]]{4}"));//false
    }
}

4.2、正则表达式的使用详解

  • 字符串对象提供了匹配正则表达式的方法

image-20230810160533893.png

4.3、正则表达式的常见案例

  • 【需求】
    • 请编写程序模拟用户输入手机号码、验证格式正确,并给出提示,直到输入正确为止
    • 请编写程序模拟用户输入邮箱号码、验证格式正确,并给出提示,直到输入正确为止
    • 请编写程序模拟用户输入电话号码、验证格式正确,并给出提示,直到输入正确为止
public class Demo2 {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        //System.out.println("请输入手机号码:");
        //System.out.println("请输入邮箱:");
        //System.out.println("请输入电话号码:");
        while(true){
            if(CheckQQE_mail(input.next())){
                System.out.println("输入成功,格式正确!");
                break;
            }
            System.out.println("输入错误");
        }
    }
    public static boolean checkPhoneNum(String phoneNum){

        return phoneNum.matches("1[3-9]\\d{9}");
    }
    public static boolean CheckQQE_mail(String email){
        return email.matches("\\w{4,11}@[a-zA-Z0-9]{2,20}(\\.[a-zA-Z0-9]{2,20}){1,2}");
    }
    //电话号码校验
    public static boolean number(String num){
        return num.matches("0\\d{2,6}-?\\d{5,20}");
    }
}

4.4、正则表达式在方法种的应用

image-20230810160542358.png

4.5、正则表达式爬取信息

public class Demo3 {
    public static void main(String[] args) {
        //爬取信息
        String str = "月老相亲cp,电话020-43422424,或者联系邮箱itcase@itcast.cn,电话15836559567,0203232323" +
                "邮箱bozai@itcase.cn,400-100-3222,4001002222";
        //从上面信息取出邮箱和电话
        //1.定义规则,字符串形式
        String regex = "(\\w{1,30}@[a-zA-Z0-9]{2,20}(\\.[a-zA-Z0-9]{2,20}){1,2})|" +
                " (1[3-9]\\d{9})|(0\\d{2,6}-?\\d{5,20})|(400-?\\d{3,9}-?\\d{3,9})";
        //2.吧这个爬取规则编译为匹配对象
        Pattern pattern = Pattern.compile(regex);
        //3.得到内容匹配器
        Matcher matcher = pattern.matcher(str);
        while(matcher.find()){
            System.out.println(matcher.group());
        }
    }
}

5.Arrays类

5.1、Arrays类概述,常用功能

  • 概述
    • 数组操作工具类,专门用于操作数组元素
  • 常用API

image-20230810160550471.png

public class Demo1 {
    public static void main(String[] args) {
        //使用ArraysAPI来便利数组内容
        int[] arr = {2,30,40,22,4,90,200};
        System.out.println("遍历内容:"+Arrays.toString(arr));
        //排序:升序排
        Arrays.sort(arr);
        System.out.println("排序后:"+Arrays.toString(arr));
        //二分搜索技术(前提数组必须排序)
        int index = Arrays.binarySearch(arr,90);
        System.out.println(index);
    }
}

5.2、Arrays类对于Comparator比较器支持

  • 自定义排序规则
    • 设置Comparator接口对应的比较器对象,来定制比较规则

image-20230810160557850.png

public class ComparatorDemo {
    public static void main(String[] args) {
        //降序排序
        Integer[] arr = {34,2,55,78,10,40};
        Arrays.sort(arr,new Comparator<Integer>(){
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });
        System.out.println(Arrays.toString(arr));

        //使用对象存储,然后排序输出
        Student[] students = new Student[4];
        students[0] = new Student("马浩楠",21,180);
        students[1] = new Student("程明辉",80,160);
        students[2] = new Student("李泽",13,150);
        students[3] = new Student("吴赛",28,149);
        Arrays.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                //return o1.getAge() - o2.getAge();年龄排
                return Double.compare(o1.getHeight(),o2.getHeight());
            }
        });
        System.out.println(Arrays.toString(students));
    }
}

6.常见算法

6.1、冒泡排序

  • 思路
    • 每次从数组种找出最大值放在数组的后面去
  • 实现冒泡排序的关键步骤
    • 确定总共需要几轮:数组长度 - 1
    • 每轮比较几次
    • 当前位置大于后一个位置则交换位置

image-20230810160609337.png

public class Demo2 {
    public static void main(String[] args) {
        //1.定义数组
        int[] arr = {5,1,3,2};
        //           0 1 2 3
        for (int i = 0; i < arr.length-1; i++) {
            //i=0 j=1 2 3;
            //i=1 j=2 3;
            //i=2 j=3;
            for (int j = i+1; j < arr.length; j++) {
                if(arr[i] > arr[j]){
                    int temporary = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temporary;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}

6.2、二分查找

【二分查询性能好,前提是必须排好序的数据

public class Demo3 {
    public static void main(String[] args) {
        //1.定义数组(提前排序)
        int [] arr = {10,14,16,25,28,30,35,88,100};
        //2.调用方法
        System.out.println(binarySearch(arr, 88));
    }
    //arr 查询的数组,date:查找的元素
    public static int binarySearch(int[] arr,int data){
        //1.定义左边下标和右边下标
        int leftIndex = 0;
        int rightIndex = arr.length-1;
        //2.定义循环(查找到为止即左边下标和右边下标相遇)
        while(leftIndex <= rightIndex){
            //3.定义折半后中间位置下标
            int middleIndex = (leftIndex+rightIndex)/2;
            if(data>arr[middleIndex]){
                //查询的元素大于中间下标位置元素,说明需要查找的元素还在后面
                leftIndex = middleIndex+1;
            }else if(data<arr[middleIndex]){
                //查询的元素小于中间下标位置元素,说明需要查找的元素在前面
                rightIndex = middleIndex-1;
            }else {
                return middleIndex;
            }
        }
        return -1;
    }
}

7.Lambda表达式

7.1、Lambda概述

  • Lambda表达式是JDK8开始后的一种新语法形式
  • 作用:简化匿名内部类的代码写法

  • 简化格式

image-20230810160620590.png

【注意】:Lambda表达式只能简化函数式接口的匿名内部类写法形式

  • 什么是函数式接口
    • 必须是接口,且接口种只有一个抽象方法的形式
public class Demo1 {
    public static void main(String[] args) {
        //学会使用Lambda  [注意:使用的前提是接口且接口只能存在一个方法】
        //老式写法:
        /*Swimming s1 = new Swimming() {
            @Override
            public void swim() {
                System.out.println("正在游泳!");
            }
        };*/
        //Lambda方式
        Swimming s = () ->{
            System.out.println("正在游泳!");
        };
        go(s);
        //更为简化方式:直接调用
        go(()->{
            System.out.println("正在游泳");
        });
    }
    public static void go(Swimming s){
        System.out.println("开始------");
        s.swim();
        System.out.println("结束------");
    }
}
@FunctionalInterface//注解表示:标记该接口必须满足函数式接口
interface Swimming{
    void swim();
}

7.2、Lambda表达式的省略规则

  • 参数类型可以省略不写
  • 如果只有一个参数,参数类型可以省略的同时()也可以省略
  • 如果Lambda表达式的方法体只有一行代码。可以省略大括号不写,同时要省略分号!
  • 如果Lambda表达式的方法体只有一个代码。可以省略大括号不写。此时,如果这行代码是returen语句,必须省略return不写,同时也省略";"不写
public class Demo2 {
    public static void main(String[] args) {
        Integer[] arr = {5,3,1,4,2};
        //进行降序排序(之前的方式):
        /*Arrays.sort(arr, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2-o1;
            }
        });*/
        //简化后
        /*Arrays.sort(arr,(o1,o2)->{
            return o2-o1;
        });*/
        //需要返回值且只有一行代码,进一步简化:
        Arrays.sort(arr,(o1,o2)-> o2-o1);
        System.out.println(Arrays.toString(arr));
    }
}

results matching ""

    No results matching ""