重生之小比特头像
关注
【Java SE】常用工具类介绍封面图

【Java SE】常用工具类介绍

 

目录

本节学习目标

第一部分 日期相关类

1.1 旧版 Date 类(java.util.Date)

1.2 Java8 新时间 API(java.time 包,重点掌握)

1.2.1 获取当前系统时间、指定时间、字符串解析

1.2.2 获取时间各个字段(年、月、日、时、分、秒)

1.2.3 日期加减运算 plus /minus

1.2.4 TemporalAdjusters 时间调节器,获取边界时间(高频业务)

第二部分 BigDecimal 高精度运算

2.1 构造对象(重点坑!不要直接传 double)

2.2 加减乘运算

2.3 除法运算(高频坑)

📔本篇核心考点总结


本节学习目标

  1. 了解旧版java.util.Date日期类,知道大部分 API 已经过时
  2. 熟练掌握 Java8 全新时间日期 API:LocalDateTimeDateTimeFormatterTemporalAdjusters
  3. 掌握日期获取、构造、字符串解析格式化、日期加减运算、获取周 / 月 / 年边界
  4. 掌握BigDecimal大高精度浮点数类,解决 double 浮点精度丢失问题
  5. 掌握 BigDecimal 构造注意事项、加减乘除运算、除法舍入模式

第一部分 日期相关类

1.1 旧版 Date 类(java.util.Date)

Date是 Java 早期提供代表时间日期的类,时间精确到毫秒

⚠️大量构造方法、成员方法已经被@Deprecated标记为过时废弃,不推荐新项目使用,了解即可。

import java.util.Date;

public class TestDate {
    public static void main(String[] args) {
        // 获取系统当前时间
        Date date1 = new Date();
        System.out.println(date1);

        // 【已过时,不推荐使用】
        // 参数年份:是相对于1900的偏移量,123 → 1900+123 =2023年
        // 月份从0开始!0代表一月,2代表3月
        Date date2 = new Date(123,2,5);
        System.out.println(date2);
    }
}

旧 Date 痛点:

  1. 年份需要 + 1900,月份 0 开始,极易写错;
  2. 可变对象,时间可以被修改,线程不安全;
  3. API 设计混乱,大部分方法废弃。 ✅Java8 及以后优先使用新时间包 java.time

1.2 Java8 新时间 API(java.time 包,重点掌握)

核心类:

  • LocalDateTime日期 + 时间(年月日时分秒)
  • LocalDate:只有年月日
  • LocalTime:只有时分秒
  • DateTimeFormatter:日期字符串格式化解析器
  • TemporalAdjusters:时间调节器,获取当月第一天、当周周一、周日等

重要特性:LocalDateTime 对象不可变!所有 plus/minus/with 操作,返回全新对象,原对象本身不会修改。

1.2.1 获取当前系统时间、指定时间、字符串解析
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class TestLocalDateTime {
    public static void main(String[] args) {
        //1 获取系统当前的日期时间
        LocalDateTime now = LocalDateTime.now();
        System.out.println("当前时间:" + now);

        //2 手动指定年月日时分秒,构造时间对象 of(year,month,day,hour,minute,second)
        LocalDateTime dt = LocalDateTime.of(2023,5,15,10,30);
        System.out.println("指定时间:" + dt);

        //3 按照标准ISO格式字符串解析 "yyyy‑MM‑ddTHH:mm:ss"
        LocalDateTime parse1 = LocalDateTime.parse("2023-05-15T10:30:00");
        System.out.println(parse1);

        //4 自定义格式字符串解析(业务最常用)
        String dateStr = "2026-10-01 10:30:21";
        //注意大小写!yyyy年 MM月 dd日 HH24小时制 mm分钟 ss秒
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime parse2 = LocalDateTime.parse(dateStr, formatter);
        System.out.println("自定义解析结果:" + parse2);
    }
}

⚠️格式模板大小写大坑,千万不能写混:

  • yyyy:4 位年份;MM两位月份;dd两位日期
  • HH 24 小时;hh12 小时;mm分钟;ss
1.2.2 获取时间各个字段(年、月、日、时、分、秒)
import java.time.LocalDateTime;

public class TestGetTimeField {
    public static void main(String[] args) {
        LocalDateTime dateTime = LocalDateTime.now();

        int year = dateTime.getYear();                //年
        int month = dateTime.getMonthValue();         //月份【1‑12】!注意getMonth()返回枚举,getMonthValue返回数字
        int day = dateTime.getDayOfMonth();           //当月几号
        int hour = dateTime.getHour();                //小时
        int minute = dateTime.getMinute();            //分钟
        int second = dateTime.getSecond();            //秒

        System.out.println("年:"+year);
        System.out.println("月:"+month);
        System.out.println("日:"+day);
        System.out.println("时:"+hour);
        System.out.println("分:"+minute);
        System.out.println("秒:"+second);

        //附加信息
        System.out.println("本周星期几(1=周一,7=周日):" + dateTime.getDayOfWeek().getValue());
        System.out.println("本月的第几天:" + dateTime.getDayOfMonth());
        System.out.println("当年的第几天:" + dateTime.getDayOfYear());
    }
}
1.2.3 日期加减运算 plus /minus

plusXXX() 增加时间;minusXXX()减少时间;返回新对象,原对象不变!

import java.time.LocalDateTime;

public class TestTimePlusMinus {
    public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.now();

        //增加、减少天数
        LocalDateTime plus1Day = now.plusDays(1);
        LocalDateTime minus1Day = now.minusDays(1);
        System.out.println("加1天:" + plus1Day);
        System.out.println("减1天:" + minus1Day);

        //增加、减少周
        LocalDateTime plusWeek = now.plusWeeks(1);
        LocalDateTime minusWeek = now.minusWeeks(1);
        System.out.println("加1周:" + plusWeek);

        //增加、减少月份
        LocalDateTime plusMonth = now.plusMonths(1);
        LocalDateTime minusMonth = now.minusMonths(1);
        System.out.println("加1月:" + plusMonth);

        //增加、减少年份
        LocalDateTime plusYear = now.plusYears(1);
        LocalDateTime minusYear = now.minusYears(1);
        System.out.println("加1年:" + plusYear);
    }
}
1.2.4 TemporalAdjusters 时间调节器,获取边界时间(高频业务)

TemporalAdjusters可以获取:当周周一 / 周日,当月第一天、当月最后一天。

import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;

public class TestAdjust {
    public static void main(String[] args) {
        LocalDateTime current = LocalDateTime.now();

        // 获取本周周一:previousOrSame 当前或者往前找最近的周一
        LocalDateTime monday = current.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
        // 获取本周周日:nextOrSame 当前或者往后找最近的周日
        LocalDateTime sunday = current.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
        System.out.println("本周周一:" + monday);
        System.out.println("本周周日:" + sunday);

        // 获取当月第一天,当月最后一天
        LocalDateTime firstDayOfMonth = current.with(TemporalAdjusters.firstDayOfMonth());
        LocalDateTime lastDayOfMonth = current.with(TemporalAdjusters.lastDayOfMonth());
        System.out.println("当月第一天:" + firstDayOfMonth);
        System.out.println("当月最后一天:" + lastDayOfMonth);
    }
}

方法说明

  • previousOrSame:取当前或者往前找匹配星期
  • nextOrSame:取当前或者往后找匹配星期

补充:LocalDateTime 是不可变类,.with()会返回全新时间对象,原 current 对象不会被修改。

第二部分 BigDecimal 高精度运算

包:java.math.BigDecimal double/float 二进制浮点数,会有精度丢失,金融、货币计算,绝对不能直接使用 doubleBigDecimal实现十进制高精度数字运算,解决浮点精度丢失。

2.1 构造对象(重点坑!不要直接传 double)

import java.math.BigDecimal;

public class TestBigDecimalCreate {
    public static void main(String[] args) {
        // ❌不推荐:传入double,double本身已经精度丢失,BigDecimal保存的是失真之后的值
        BigDecimal num1 = new BigDecimal(1.99);
        System.out.println(num1);
        //输出:1.9899999999999999911182158029987476766109466552734375

        // ✅推荐!使用字符串构造,精确表示十进制小数
        BigDecimal num2 = new BigDecimal("2.99");
        System.out.println(num2);

        // 如果必须把double转为BigDecimal,使用静态方法 valueOf()
        double d = 3.14;
        BigDecimal num3 = BigDecimal.valueOf(d);
        System.out.println(num3);
    }
}

官方文档说明:

  1. new BigDecimal(double val):把二进制浮点数精确还原,不能用来做十进制精确计算,尽量避开
  2. new BigDecimal(String val):字符串构造,金融业务首选。
  3. BigDecimal.valueOf(double)等价于Double.toString(double),可以消除部分 double 失真。

2.2 加减乘运算

⚠️BigDecimal 是不可变对象!加减乘除不会修改原来对象,运算结果返回全新 BigDecimal 对象,需要接收返回值。

import java.math.BigDecimal;

public class TestBigDecimalCalc {
    public static void main(String[] args) {
        BigDecimal a = new BigDecimal("1.35");
        BigDecimal b = new BigDecimal("3.22");

        BigDecimal addRes = a.add(b);      //加法
        System.out.println("加法:" + addRes);

        BigDecimal subRes = a.subtract(b); //减法
        System.out.println("减法:" + subRes);

        BigDecimal mulRes = a.multiply(b);  //乘法
        System.out.println("乘法:" + mulRes);
    }
}

2.3 除法运算(高频坑)

如果除法结果是无限循环小数,直接调用divide(b)会抛出ArithmeticException算术异常!

// 报错版本
BigDecimal a = new BigDecimal("1.35");
BigDecimal b = new BigDecimal("3.22");
BigDecimal divRes = a.divide(b);
// Exception in thread "main" java.lang.ArithmeticException: Non‑terminating decimal expansion; no exact representable decimal result.

✅解决方案:指定保留小数位数 + 舍入模式 divide(除数,保留小数位数,舍入模式) 常用舍入模式:RoundingMode.HALF_UP 四舍五入。

import java.math.BigDecimal;
import java.math.RoundingMode;

public class TestBigDecimalDiv {
    public static void main(String[] args) {
        BigDecimal a = new BigDecimal("1.35");
        BigDecimal b = new BigDecimal("3.22");
        //保留4位小数,四舍五入
        BigDecimal divRes = a.divide(b,4, RoundingMode.HALF_UP);
        System.out.println("除法结果:" + divRes); //输出0.4193
    }
}

另一种写法,传入MathContext设置精度

BigDecimal divRes = a.divide(b, new MathContext(4,RoundingMode.HALF_UP));

📔本篇核心考点总结

  1. java.util.Date大量 API 过时,年份偏移 1900,月份从 0 开始;线程不安全,新项目不用。
  2. Java8 新时间包java.timeLocalDateTime代表日期时间,对象不可变,plus/minus/with 返回新对象,原对象不变
  3. DateTimeFormatter.ofPattern()自定义解析格式,注意大小写区分:yyyy MM dd HH mm ss
  4. TemporalAdjusters调节器:获取当周周一 / 周日、当月第一天、当月最后一天。
  5. BigDecimal用于金融高精度计算;禁止直接 new BigDecimal (double),优先字符串构造或者 valueOf ()
  6. BigDecimal 运算不会修改原对象,运算结果必须接收返回对象。
  7. divide 除法遇到无限小数会抛异常,必须指定小数位数 + 舍入模式,常用RoundingMode.HALF_UP四舍五入。

面试简答 Q:为什么金融计算不能直接用 double? A:double 是二进制浮点数,部分十进制小数无法精确存储,会产生精度丢失,金融业务用 BigDecimal。 Q:LocalDateTime plusDays 之后,原来对象时间会改变吗? A:不会,LocalDateTime 不可变,返回全新对象,原对象内容保持不变。

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/wuqingyigexiaoba/article/details/165757444

文章来源转载

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--