中南林业科技大学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("匹配失败");
        }
    }
}

【运行流程】

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);
    }

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;
}

📍 一个常用方法:

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);
    }
}

【运行流程】

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() + " 日");
        
    }
}

【运行流程】

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));
    }
    
}

【核心代码】

  • 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 +
                    '}';
        }
    }
    
  • 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);
            }
            
        }
    }
    

【运行流程】

image-20221107181613072

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 中南大学的操作系统课程实验在CSDN(中国软件开发网)上有相关的资料和指导。CSDN是一个以软件开发为主题的综合性技术社区,提供了丰富的技术文档、开发工具、学习资源等。在CSDN上搜索"中南大学操作系统课程实验",可以找到一些教程和实验指导。 这些教程和实验指导一般涵盖了操作系统的基本概念、原理和实践,帮助学生更加深入地理解操作系统的运行机制。其中可能包括实验的相关实施步骤,代码示例,实验要求和实验报告的撰写要点等等。 通过在CSDN上学习并实践中南大学操作系统课程的实验,学生可以提升他们的编程能力、了解操作系统的基本原理以及熟悉操作系统的设计与实现。此外,CSDN社区还提供了各种论坛和资源下载,学生可以在这里与其他同学、开发者交流,并获取更多有关操作系统的资料和经验分享。 总之,通过CSDN上的操作系统课程实验中南大学的学生可以更好地掌握操作系统的理论知识,提高自己的实践能力,并与其他同学共同进步。 ### 回答2: 中南大学的操作系统课程实验是一个非常实用和有趣的课程实践。在这门课程中,学生将通过实际操作,深入理解操作系统的运行原理和实现方式。 这门实验在课程中会涉及到多个实验项目,其中包括进程管理、内存管理、文件系统等多个方面。学生们将会学习到操作系统的基本概念、结构和功能,并通过编写代码,实现这些功能。通过实验,同学们能够更好地理解操作系统的运行机制,并加深对操作系统的学习和理解。 这门实验还具有一定的挑战性。在完成实验任务的过程中,学生需要运用所学的知识,设计合理的算法和数据结构,以实现所需功能。在实验过程中,同学们还需面对一些常见的问题和困难,例如处理同步问题、解决死锁等。通过解决这些问题,同学们能够提升自己的编程能力和解决问题的能力。 此外,中南大学操作系统课程实验还提供了多种实验环境供同学们进行实验。学生可通过使用C/C++等编程语言和Linux系统,实现操作系统相关功能。同时,学生们还可以利用CSDN这一资源平台,参考他人的实验代码和经验,加深对操作系统的理解。 总之,中南大学操作系统课程实验通过实际操作,提供了一个深入理解操作系统的机会。同学们通过编写代码,实现操作系统的各项功能,提升了自己的编程和解决问题的能力。这门课程实验在操作系统学习中起到了重要的作用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是谢添啊

感谢你的支持,我会继续加油的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值