Java复习笔记-16

工具类

1 数学类

1.1 BigInteger类

用于进行大量数字存储和计算的类

public static void main(String[] args) {
        // 用于大量数值的存储和计算
        BigInteger bigInteger = new BigInteger("456463546335465436757657564765474657654765846786786576576576576547654765476547456463546335465436757657564765474657654765846786786576576576576547654765476547456463546335465436757657564765474657654765846786785436757657564765474657654765846786786576576576576547654765476547");
        BigInteger bigInteger1 = new BigInteger("4564635463354654367576575647654746576547658467867865765765765765476547654765474564635463354463546335465436757657564765474657654765");
        // 乘
        System.out.println(bigInteger.multiply(bigInteger1));
        // 加
        System.out.println(bigInteger.add(bigInteger1));
        // 除
        System.out.println(bigInteger.divide(bigInteger1));
        System.out.println(bigInteger.subtract(bigInteger1));
    }

1.2 BigDecimal类

用于精确运算的类,要求参数以字符串形式传递

    private static void demo2() {
        // 在java中是不能进行精确运算
//        double d = 3.00;
//        double d1 = 2.99;
//        System.out.println(d - d1);
        // 这里想要精确计算,必须使用字符串存储,底层会按照小数点进行按位运算
        BigDecimal bigDecimal = new BigDecimal("3.00");
        BigDecimal bigDecimal1 = new BigDecimal("2.99");
        System.out.println(bigDecimal.subtract(bigDecimal1));
    }

1.3 DecimalFormat类

这个类用于数字固定格式转换

private static void demo3() {
        double d = 50.89 * 0.81;
        System.out.println(d);

        // 创建对象并且指定数据显示的格式
        // 用0来表示占位,表示一个数字,如果这一位没有数字,用0代替
        // #代表占位,表示一位数字,如果这一位没有数字,那么就不填充内容。如果有数字就填充内容。
        // 0#.00会直接抛出异常,因为不符合常理
//        DecimalFormat decimalFormat = new DecimalFormat("#0.00");
        // 科学计数法
        DecimalFormat decimalFormat = new DecimalFormat("0.0E0");
        System.out.println(decimalFormat.format(d));
    }

1.4 面试题分享

  • 两个千位数字相乘,有几种解决方案?
    • BigInteger类可以轻松解决
    • 还有没有其他解决方案?

分析:怎么存储?

String或者数组.

怎么乘?

int[] arr1 = {1, 9, 9, 8};
        int[] arr2 = {1, 7, 7, 6};
        int[] arr3 = new int[arr1.length + arr2.length];
        for (int i = 0; i < arr2.length; i++) {
            for (int j = 0;j < arr1.length;j++){
                arr3[i + j] += arr2[j] * arr1[i];
            }
        }

        for(int i = arr3.length - 2;i > 0;i--){
            int temp = arr3[i];
            arr3[i] = arr3[i] % 10;
            arr3[i - 1 ] += (temp / 10);
        }
        if(arr3[0] >= 10){
            int[] arr4 = new int[arr3.length];
            arr4[0] = arr3[0] / 10;
            arr4[1] = arr3[0] % 10;
             int[] arr5 = Arrays.copyOfRange(arr3,1,arr3.length - 1);
            System.arraycopy(arr5,0,arr4,2,arr5.length);
            System.out.println(Arrays.toString(arr4));
        }else {
            int[] arr4 = Arrays.copyOfRange(arr3,0,arr3.length - 1);
            System.out.println(Arrays.toString(arr4));
        }

日期&异常

1 日期

1.1 日期Date类的格式化

  • 日期转换成字符串
public static void main(String[] args) {
        // 获取当前时间
        Date date = new Date();
        System.out.println(date);

        // 创建日期格式化对象  2023-08-29 10:13:59
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS EE a");
        String str = simpleDateFormat.format(date);
        System.out.println(str);
    }
  • 字符串转日期
public static void main(String[] args) throws ParseException {
        // 1999-12-01
        // 字符串转日期
        String str = "1999-12-01";
        // 创建日期格式化对象
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = simpleDateFormat.parse(str);
        System.out.println(date);
    }

1.2 日历类

private static void demo3() {
        // 获取当前时间的日历类
        Calendar calendar = Calendar.getInstance();
        System.out.println(calendar);
        // field : 属性
        int year = calendar.get(Calendar.YEAR);
        System.out.println("年是" + year);
        int month = calendar.get(Calendar.MONTH);
        System.out.println("月是" + (month + 1));
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.println("日是" + day);

        Date date = new Date(1234242354345L);
        System.out.println(new SimpleDateFormat("yyyy-MM-dd").format(date));
        System.out.println(date);
        // 设置日历类的时间
        calendar.setTime(date);
        System.out.println(calendar.get(Calendar.YEAR));
        System.out.println(calendar.get(Calendar.WEEK_OF_MONTH));

    }

练习:上海股市每一个月的第三周的周六进行交易,其他时间是无法交易的。输入一个时间(2024-09-01),判断这个时间是否允许交易并提示:交易未开始,交易已结束,交易正在进行中。

private static void practice01() throws ParseException {
//        上海股市每一个月的第三周的周六进行交易,其他时间是无法交易的。
//        输入一个时间(2024-09-01),判断这个时间是否允许交易并提示:交易未开始,交易已结束,交易正在进行中。

        // 1.用户输入一个字符串时间
        System.out.println("请输入您想查询的日期");
        Scanner scanner = new Scanner(System.in);
        String str = scanner.next();
        // 2.把字符串时间转换成日期对象
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = simpleDateFormat.parse(str);
        // 3.设置日历对象的日期
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 4.获取第几周,获取周几
        // DAY_OF_WEEK_IN_MONTH从把1号看作这个月的第一周
        // 第几周
        int week = calendar.get(Calendar.WEEK_OF_MONTH);
        // 周几
        int day = calendar.get(Calendar.DAY_OF_WEEK);
        // 5.判断
        if (week == 3 && day == 7){
            System.out.println("交易正在进行中");
        }else if(week < 3 || week == 3 && day < 7){
            System.out.println("交易未开始");
        }else {
            System.out.println("交易已结束");
        }
    }

1.3 java.time包

在JDK1.8之后,对时间体系进行了新的划分,将日期和时间以及其他的信息进行分割,从而分出来一个代表时间的包–java.time

1.3.1 LocalDate

这个类中只能表示年月日,没有时分秒

private static void demo4() {
        // 获取当前日期
        LocalDate date = LocalDate.now();
        System.out.println(date);

        // 指定日期
        LocalDate date1 = LocalDate.of(1998, 2, 28);
        System.out.println(date1);
        // 增加时间
        date1 = date1.plus(3, ChronoUnit.DAYS);
        System.out.println(date1);
        // 减少时间
        System.out.println(date1.minus(10, ChronoUnit.MONTHS));
    }
1.3.2 LocalTime

这个类中只能表示时分秒毫秒微妙纳秒,没有日期

// LocalTime
        // 获取当前时间
        LocalTime now = LocalTime.now();
        System.out.println(now);
        // 指定时间
        LocalTime of = LocalTime.of(10, 25, 9);
        System.out.println(of);
        // 增加时间
        of = of.plus(3, ChronoUnit.HOURS);
        System.out.println(of);
		// 减少时间
        System.out.println(of.minus(4, ChronoUnit.HOURS));
1.3.3 LocalDateTime

这个类中有年月日时分秒毫秒微妙纳秒

private static void demo6() {
        // 获取当前年月日时分秒毫秒纳秒
        LocalDateTime dateTime = LocalDateTime.now();
        System.out.println(dateTime);
        // 指定时间
        LocalDateTime of = LocalDateTime.of(2019, 9, 10, 10, 1);
        System.out.println(of);
        // 增加时间
        System.out.println(dateTime.plus(3, ChronoUnit.YEARS));
        // 减少时间
        System.out.println(dateTime.minus(4,ChronoUnit.MINUTES));
    }
1.3.4 Instant类

Instant类是JDK8中推荐用来替换Date类。可以精确到纳秒。Date类只能精确到毫秒。

private static void demo7() {
        // 默认获取的是世界时间
        Instant now = Instant.now();
        System.out.println(now);
        // 获取北京时间
//        now = now.plus(8,ChronoUnit.HOURS);
//        now = now.plusSeconds(8 * 60 * 60);
//        System.out.println(now);

        // 获取毫秒
        System.out.println(now.get(ChronoField.MILLI_OF_SECOND));
        // 获取微妙
        System.out.println(now.get(ChronoField.MICRO_OF_SECOND));
        // 获取纳秒
        System.out.println(now.get(ChronoField.NANO_OF_SECOND));

        // 转换成LocalDateTime  ZoneId.systemDefault(): 默认系统时区
        LocalDateTime localDateTime = LocalDateTime.ofInstant(now, ZoneId.systemDefault());
        System.out.println(localDateTime);
    }
1.3.5 字符串和JDK8日期类型转换
  • LocalDate和String相互转换
private static void demo8() {
        LocalDate date1 = LocalDate.of(2023,8,29);
        System.out.println(date1);
        // 日期格式化对象
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        String format = timeFormatter.format(date1);
        System.out.println(format);

        // 字符串转日期
        LocalDate parse = LocalDate.parse(format, timeFormatter);
        System.out.println(parse);
    }
  • LocalDateTime和String相互转换
private static void demo9() {
        // 日期转字符串
        LocalDateTime localDateTime = LocalDateTime.of(2023,8,29,15,13,20);
        System.out.println(localDateTime);
        // 日期转换对象
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        String format = dateTimeFormatter.format(localDateTime);
        System.out.println(format);

        // 字符串转日期
        LocalDateTime parse = LocalDateTime.parse(format,dateTimeFormatter);
        System.out.println(parse);
    }

2 异常

2.1 异常介绍

异常和错误有一个顶级的父类Throwable.

Throwable有两个子类

  • Error错误
    • 是所有错误的父类,表示程序中出现了非常严重的问题,不修改源码程序不能执行
  • Exception异常
    • 表示所有异常的父类,程序中出现了一般性的问题,程序员处理后代码可以继续向下执行
    • 异常分为编译时异常和运行时异常
    • 不是RuntimeException及其子类的异常都是编译时异常
    • 编译时异常在编译期间就会报错,必须处理。
    • 运行时异常在运行时会出错,编译期间不需要处理

2.2 throw和throws用法

throw是在方法内部手动new一个异常,告诉调用者

throws是声明可能遇到的异常,但是不处理,让别人处理

    public static void main(String[] args) throws ParseException {
        int[] arr = {1,2,3,4,5,6};
        int element = getElement(arr);
        System.out.println(element);
    }

    public static int getElement(int[] arr) throws ParseException {
        // 数组中没有对应5的索引,JVM检测到出现了问题,JVM就会创建一个异常对象
        // 这个异常会抛出给调用的方法,就是main方法
        // main方法收到了异常,main方法自己不会处理,main方法接着将异常抛出去给JVM
        // JVM不会处理,做了2件事情
        // 1。就是把异常的信息打印在控制台
        // 2. 停止程序
//        throw new ArrayIndexOutOfBoundsException();
        if (arr == null){
            throw new NullPointerException("数组arr是一个null");
        }
        if (arr.length < 6) {
            throw new ArrayIndexOutOfBoundsException("数组的长度不合法");
        }

        method();
        return arr[5];
    }

    public static void method() throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy");
        simpleDateFormat.parse("");
    }

2.3 自定义异常

自定义异常需要继承Exception或者其子类。

如果继承了RuntimeException就是一个运行时异常

如果继承的不是RuntimeException就是编译时异常

自定义异常需要提供一个无参构造和一个有参构造,有参构造中直接调用父类的有参构造方法

class FileFormatException extends Exception{
    

    public FileFormatException(){}

    public FileFormatException(String message){
        super(message);
    }
}


// 自定义异常  如果继承RuntimeException 就是一个运行时异常
// 如果没有继承RuntimeException及其子类,那么就是一个编译时异常
class PathNotExistException extends Exception{

    public PathNotExistException(){}

    public PathNotExistException(String message){
        super(message);
    }

}

2.4 捕获异常

使用try…catch可以捕获编译时和运行时异常

在try编写可能会出现异常的代码,catch中处理异常

/**
         * 可以使用try{}catch{}来捕获异常,从而处理异常
         * 格式:
         * try{
         *     被检测的代码,有可能出现异常的代码;
         * }catch(要捕获的异常类 变量名){
         *     对于异常的处理方法(写循环,判断,调用方法...)
         *     只要代码到catch中,说明已经已经处理了,代码就可以继续向下执行了
         * }
         * try中出现异常,程序执行catch,代码会继续向下执行
         * try中出现异常,程序不执行catch,代码不会继续向下执行
         * 如果捕获到异常,会把异常的对象赋值给catch中的变量
         */
        String str = null;
        try {
            str = readTxt("E:\\a.jpg");
        } catch (PathNotExistException e) {
            // getMessage()获取异常的信息
            System.out.println(e.getMessage());
        }catch (NullPointerException e){
            System.out.println(e.getMessage());
        } catch (FileFormatException e) {
            // 打印异常的栈轨迹
            e.printStackTrace();
        }
        System.out.println("程序继续向下执行");
        System.out.println(str);

案例

public static void main(String[] args) {
        System.out.println(parseText("1998/04/17"));

    }

    // 假设公司一种日期表示格式是用-  一种使用/
    public static Date parseText(String str){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = simpleDateFormat.parse(str);
        } catch (ParseException e) {
            simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
            try {
                date = simpleDateFormat.parse(str);
            } catch (ParseException ex) {

            }
        }
        return date;
    }

2.5 异常的捕获方式

  • 如果出现了多个异常,并且每一个异常的处理方式都不一样,可以使用多个catch分别捕获来处理。
String str = null;
        try {
            str = readTxt("E:\\a.jpg");
        } catch (PathNotExistException e) {
            // getMessage()获取异常的信息
            System.out.println("修改文件路径");
            System.out.println(e.getMessage());
        }catch (NullPointerException e){
            System.out.println("重新赋值");
            System.out.println(e.getMessage());
        } catch (FileFormatException e) {
            System.out.println("修改文件格式");
            // 打印异常的栈轨迹
            e.printStackTrace();
        }
        System.out.println("程序继续向下执行");
        System.out.println(str);
  • 如果所有的异常的处理方式都一样,可以捕获这些异常的共同的父类,然后在一个catch中统一处理
		String str = null;
        try {
            str = readTxt("E:\\a.jpg");
        } catch (Exception e) {
            // 打印异常的栈轨迹
            e.printStackTrace();
        }
        System.out.println("程序继续向下执行");
        System.out.println(str);
  • 如果异常的处理进行了分组,那么同一组异常之间用|隔开,从而可以分组处理
    • JDK1.7后可以使用
		String str = null;
        try {
            str = readTxt("E:\\a.jpg");
        } catch (PathNotExistException e) {
            System.out.println("文件不存在异常");
            
        }catch (NullPointerException | FileFormatException  e){
            // 打印异常的栈轨迹
            e.printStackTrace();
        } 
        System.out.println("程序继续向下执行");
        System.out.println(str);

注意: 捕获异常的时候需要先捕获子类,再捕获父类

		String str = null;
        try {
            str = readTxt("E:\\a.jpg");
        }catch (NullPointerException e){
            // 打印异常的栈轨迹
            e.printStackTrace();
        } catch (FileFormatException e) {
            // 打印异常的栈轨迹
            e.printStackTrace();
        } catch (Exception e) {
            System.out.println("文件不存在异常");
        }
        System.out.println("程序继续向下执行");
        System.out.println(str);

如果先捕获Exception,已经包含了NullPointerException和FileFormatException,所有后面的捕获异常等于没有写

2.6 异常对于方法重写和重载的影响

  • 异常对于重载没有影响。
  • 在方法重写的时候,子类抛出的编译时异常不能超过父类对应方法的编译时异常的范围
class A {
    public void m()throws IOException {

    }

    public void m(int i) throws ParseException{

    }
}

class B extends A{
    // 因为FileNotFoundException是IOException的子类
    public void m() throws FileNotFoundException {

    }
}

2.7 finally

用于修饰代码块,被finally修饰的代码块无论是否出现异常都一定会执行

	try {
            System.out.println(1 / 0);
        } finally {
            System.out.println("finally...");
        }

        System.out.println("hello");

try-catch和finally连用时,在编译阶段会认为try中的代码不一定执行

		String str;
        try {
            str = "abc";
        }catch (Exception e){
            
        } finally{
            System.out.println("finally...");
        }
        // java认为str在try中可能会出现异常,所以这里编译失败
        System.out.println(str);
        System.out.println("hello");

2.8 面试题

  • 第一种情况 结果是7和9
public static int demo02(){
        /**
         * 代码是从上到下编译和运行的
         * 先进入到try代码块中,然后获取i的值是7,由于++符号在i的后面
         *  所以JVM先标记i的值为7,然后进行return操作,i自增为8
         *  在要return标记值7的时候,受到try的影响,要检查下有没有finally代码块
         *  检查到有finally,继续执行,i++,结果是9
         *  如果finally中的代码是return i++,那么就会将第一次自增后的8返回出去
         */
        int i = 7;
        try {
            return i++;
        }finally {
            i++;
            System.out.println("finally中的i的值是" + i);
        }
    }
  • 第二种情况 结果是 8 8
public static int demo02(){
        /**
         * 代码是从上到下编译和运行的
         * 先进入到try代码块中,然后获取i的值是7,由于++符号在i的后面
         *  所以JVM先标记i的值为7,然后进行return操作,i自增为8
         *  在要return标记值7的时候,受到try的影响,要检查下有没有finally代码块
         *  检查到有finally,继续执行,i++,结果是9
         *  如果finally中的代码是return i++,那么就会将第一次自增后的8返回出去
         */
        int i = 7;
        try {
            return i++;
        }finally {
            System.out.println("finally中的i的值是" + i);
            return i++;
        }
    }
  • 情况三
private static Person demo03() {
        Person person = new Person();
        try {
            person.setName("刘翔");
            person.setAge(20);
            // 因为返回的是一个对象,是同一个地址
            // 在执行finally时,会将同一个地址person中的属性修改。所以结果是姚明
            return person;
        }finally {
            person.setName("姚明");
            person.setAge(30);
        }

    }
  • 情况四
private static Person demo03() {
        Person person = new Person();
        try {
            person.setName("刘翔");
            person.setAge(20);
            // 0x111
            return person;
        }finally {
            // 0x222
            // 这种情况结果是刘翔
            person = new Person();
            person.setName("姚明");
            person.setAge(30);
        }
    }
  • 情况五
private static String demo04() {
        String str;
        try {
            str = "abc";
            return str;
        }finally {
            // 地址已经发生改变,所以返回的str还是原来的abc
            str = "def";
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值