• 中南林业科技大学Java实验报告十:常用实用类


    实验10 常用实用类

    10.1 实验目的

    1. 理解String类的特性,熟练掌握String类的常用方法。
    2. 掌握正则表达式的使用方法。
    3. 能用日期类创建对象,熟练掌握日期类的常用方法。
    4. Arrays类的常用方法使用。

    10.2 实验内容

    10.2.1 编写一个正则表达式,自己定义一个String类型的字符验证是否满足该正则表达式。(比如可以验证字符串是否以a开头,以b结尾的字符串,其正则表达式为:regx=a.*b)

    【前提引入】

    1️⃣ 字符匹配符 —— “ . ”

    符号名称示例解释
    .匹配出\n以外的任何字符a…b以a开头,b结尾,中间包括2个任意字符的长度为4的字符串
    []可接收的字符列表[efgh]是 e、f、g、h 中的任意一个字符

    2️⃣ 选择匹配符 —— " * "

    符号名称示例解释
    *指定字符重复0次或多次(abc)*仅包含任意个 abc 的字符串出现0或多次
    +指定字符重复1次或多次m+abc以至少一个m开头后接abc

    3️⃣ 定位符

    符号名称示例解释
    ^指定起始开始字符^a+[a-z]$以至少一个a开头,后接任意个小写字母的字符串
    $指定结束字符^[0-9]+c$以至少一个数字开头,后接字母c结尾的字符串

    📍 那怎样写以 a 开头,以 b 结尾的字符串呢?

    • 以a开头:^a
    • 以b结尾:b$
    • 中间字符串任意对应 .,有或没有都可以 对应 *,因此组合起来是:.*

    所以组合起来就是:^a.*b$

    3️⃣ String类中具有判断功能的 matches 方法

    解读:public boolean matches(String regex)

    该方法是进行整体匹配,相当自带 ^ 和 $

    既然自带了,那么以a开头,以b结尾的字符串就可以由原来的 ^a.*b$ 写为 a.*b

    当然,如果你写的是 matches(“^a.*b$”) 这也是对的,完全等价于 matches(“a.*b”)。

    【核心代码】

    import java.util.Scanner;
    
    public class RegxTest {
        public static void main(String[] args) {
            //创建一个扫描器对象
            Scanner scanner = new Scanner(System.in);
            //通过键盘输入字符串
            String str = scanner.next();
            //进行正则匹配,调用 matches 方法
            if(str.matches("a.*b")){
                System.out.println("匹配成功");
            }else{
                System.out.println("匹配失败");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    【运行流程】

    image-20221106192641294

    image-20221106192704828

    10.2.2 利用Pattern类和Matcher类以及其类中的方法,统计字符串str1,在str2中出现的次数。

    【前提引入】

    1️⃣ Pattern类

    Pattern类对象是一个正则表达式对象。Pattern类没有公共的构造的方法:

    image-20221107165535463

    因此要创建一个 Pattern 类对象,需要调用其公共的静态方法compile,它会返回一个Pattern对象。该方法接收一个正则表达式作为它的第一个参数,看下该方法的源码:

        /**
         * Compiles the given regular expression into a pattern.
         *
         * @param  regex
         *         The expression to be compiled
         * @return the given regular expression compiled into a pattern
         * @throws  PatternSyntaxException
         *          If the expression's syntax is invalid
         */
        public static Pattern compile(String regex) {
            return new Pattern(regex, 0);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2️⃣ Matcher

    Matcher类对象是对输入字符串进行解释和匹配的引擎。与Pattern类一样,Matcher也没有公共的构造方法,需要调用Pattern对象的matcher方法来获得一个Matcher对象。

    /*
    	input:要匹配的字符序列
    */
    
    public Matcher matcher(CharSequence input) {
        if (!compiled) {
            synchronized(this) {
                if (!compiled)
                    compile();
            }
        }
        Matcher m = new Matcher(this, input);
        return m;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    📍 一个常用方法:

    public boolean find():部分匹配,找到一个匹配的子串,则返回true,并将定位移动到下次匹配的位置。

    【核心代码】

    public class RegxTest {
        public static void main(String[] args) {
            //已知字符串
            String str2 = "abc.defabc.kabc";
            //创建一个扫描器对象
            Scanner scanner = new Scanner(System.in);
            //通过键盘输入字符串
            String str1 = scanner.next();
    
            //创建Pattern类对象,参数是正则表达式规则
            Pattern pattern = Pattern.compile(str1);
            //对输入字符串 str2 依照 str1 正则表达式规则进行解释和匹配的引擎
            Matcher matcher = pattern.matcher(str2);
            //用于统计出现次数
            int count = 0;
    
            //find方法:部分匹配,找到一个匹配的子串,则返回true,并将定位移动到下次匹配的位置。
            while (matcher.find()) {
                count++;
            }
            System.out.println("出现次数:" + count);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    【运行流程】

    image-20221107165317874

    10.2.3 编写一个计算纪念日提醒的Java程序,具有倒计时功能,以及到期提醒功能(如离某某人生日还有多少天,今天是某某人生日),以及距离某一个日期已经多少天,多少小时等(如已经进入中南林业科技大学2年X月X天,注意:最少精确到天)。

    【前提引入】

    所在类是否静态方法方法返回值含义
    LocalDate静态now()LocalDate获取当前时间LocalDate对象,包括年月日
    LocalDate静态getYear()int获取对象的年份
    LocalDate静态parse(String dateStr)LocalDate将一个日期字符串dateStr解析转为LocalDate对象
    LocalDate非静态isBefore(LocalDate localDate)boolean判断对象时间是否在localDate时间之前
    LocalDate非静态isAfter(LocalDate localDate)boolean判断对象时间是否在localDate时间之后
    LocalDate非静态until(LocalDate localDate,ChronoUnit.DAYS)long返回locaDate与对象天数差
    LocalDate静态Period.between(start, end)Period两个时间相差的年月日Period对象
    Period非静态getYearsintperiod对象存储的年份
    Period非静态getMonthsintperiod对象存储的月份
    Period非静态getDaysintperiod对象存储的天数

    【核心代码】

    import java.time.LocalDate;
    import java.time.Period;
    import java.time.temporal.ChronoUnit;
    
    public class DateTest {
        public static void main(String[] args) {
            //得到当前时间(年月日)
            LocalDate now = LocalDate.now();
    
            //定义某人生日时间
            String birthday = "11-05";
            //获取当前年份
            int nowYear = now.getYear();
            //获取今年的生日时间
            LocalDate birthdayDate1 = LocalDate.parse(nowYear + "-" + birthday);
            //如果当前时间在今年生日时间之前
            if (now.isBefore(birthdayDate1)) {
                //那么可以直接计算时间差
                System.out.println("距离生日还有:" + now.until(birthdayDate1, ChronoUnit.DAYS));
            } else if (now.isAfter(birthdayDate1)) {
                //如果当前时间在今年生日时间之后,说明生日已过,那么计算距离明年生日的天数
    
                //获取明年的生日时间
                LocalDate birthdayDate2 = LocalDate.parse(nowYear + 1 + "-" + birthday);
                //计算天数差
                System.out.println("距离生日还有:" + now.until(birthdayDate2, ChronoUnit.DAYS));
            }else{
                //说明恰好是今天
                System.out.println("今天是雨浪的生日");
            }
    
            System.out.println("-------------------------------------------------------");
    
            //定义进校时间
            LocalDate intoSchoolDate = LocalDate.parse("2021-09-10");
            //得到现在与进校时间的时间差:年、月、日
            Period period = Period.between(intoSchoolDate, now);
            //输出时间差
            System.out.println("现在与进校时间相差:" + period.getYears() + " 年 " +
                    period.getMonths() + " 月 " + period.getDays() + " 日");
            
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    【运行流程】

    image-20221107180043884

    10.2.4 新建一个Student类,属性为姓名,年龄,学号,声明一个Student的对象数组,分别按照年龄和学号进行排序并输出结果。

    【前提引入】

    Arrays类:包含了一系列的静态方法,用于管理或操作数组(比如排序和搜索)

    Arrays.sort方法:因为数组是引用类型,所以通过 sort 排序后会直接影响到数组本身。sort是重载的,也可以通过传入一个接口 Comparator 实现定制排序规则,调用定制排序时,传入两个参数:

    1. 排序的数组arr

    2. 实现了Comparator接口的匿名内部类,要求重写compare方法,通过返回值的正负情况决定了排序规则。

      这充分体现了 接口编程 + 动态绑定 + 匿名内部类 的综合使用。

    📍 这里我们通过一个简单模拟来该方法的实现(对于理解Arrays的sort方法很重要):

    public class ArraysTest {
    
        /**
         * 使用 冒泡排序 + 匿名内部类 来简单模拟 Arrays.sort 方法的实现
         * 也就是说,我们在这里自定义一个sort方法
         *
         * @param arr 待排序的数组
         * @param c 实现Comparator接口的类 对象
         */
        public static void sort(int[] arr, Comparator c) {
            int temp = 0;
            for (int i = 0; i < arr.length - 1; i++) {
                for (int j = 0; j < arr.length - 1 - i; j++) {
                    //数组排序由 c.compare(arr[j], arr[j + 1])返回的值决定
                    //如果返回正数则进行交换,否则不交换
                    if (c.compare(arr[j], arr[j + 1]) > 0) {
                        temp = arr[j];
                        arr[j] = arr[j + 1];
                        arr[j + 1] = temp;
                    }
                }
            }
        }
    
        public static void main(String[] args) {
            int[] arr = {5,3,2,8,7};
    
            //从小到大排序
            sort(arr,new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    //value1 代表 arr[j] 的值
                    int value1 = (Integer)o1;
                    //value2 代表 arr[j+1] 的值
                    int value2 = (Integer)o2;
    
                    //如果返回正数,即arr[j]比arr[j+1]大时,在sort方法中会将这两个位置上的值进行交换
                    //则说明了我们指定的是从小到大进行排序
                    return value1-value2;
                }
            });
    
            //使用 Arrays.toString方法 打印数组
            System.out.println(Arrays.toString(arr));
        }
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    【核心代码】

    • Student类(为了演示方便,这里把属性的修饰符定为 public )

      package com.csuft;
      
      public class Student {
          public String name;
          public int age;
          public int studentId;
      
          public Student(String name, int age, int studentId) {
              this.name = name;
              this.age = age;
              this.studentId = studentId;
          }
      
          @Override
          public String toString() {
              return "Student{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      ", studentId=" + studentId +
                      '}';
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
    • ArraysTest类

      import java.util.Arrays;
      import java.util.Comparator;
      
      public class ArraysTest {
          public static void main(String[] args) {
              Student[] students = new Student[] {
                      new Student("雨浪",18,20212819),
                      new Student("夜莺",16,20212850),
                      new Student("狐狸半面添",17,20212880)
              };
      
              System.out.println("-------------依照年龄对数组进行 升序 排序------------");
              Arrays.sort(students, new Comparator<Student>() {
                  @Override
                  public int compare(Student o1, Student o2) {
                      return o1.age-o2.age;
                  }
              });
      
              for (Student student : students) {
                  System.out.println(student);
              }
      
              System.out.println("-------------依照学号对数组进行 降序 排序------------");
              Arrays.sort(students, new Comparator<Student>() {
                  @Override
                  public int compare(Student o1, Student o2) {
                      return o2.studentId-o1.studentId;
                  }
              });
      
              for (Student student : students) {
                  System.out.println(student);
              }
              
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37

    【运行流程】

    image-20221107181613072

  • 相关阅读:
    计算机网络第五节 网络层
    RabbitMQ是如何保证高可用的?
    2023最新SSM计算机毕业设计选题大全(附源码+LW)之java创新实践学分管理系统08a30
    从零开始做一个SDWAN
    【机器学习】Sklearn导入手写数字数据集 Mnist 失败的解决办法
    见微知著,从两道有意思的 CSS 面试题,考察你的基础
    vue下载文件时显示进度条
    14、顺时针打印矩阵
    计算机视觉全系列实战教程:(八)图像变换-点运算、灰度变换、直方图变换
    SOLIDWORKS参数化设计之格式转换 慧德敏学
  • 原文地址:https://blog.csdn.net/qq_62982856/article/details/127736766