常用API(Runtime类 BigDecimal类 Date类 SimpleDateFormat类 Calendar类)
一、Runtime类我们学习一个Java的运行时类叫Runtime类。这个类可以用来获取JVM的一些信息也可以用这个类去执行其他的程序。Runtime类提供的常见方法方法名说明public static Runtime getRuntime()返回与当前Java应用程序关联的运行时对象public void exit(int status)终止当前运行的虚拟机public int availableProcessors()返回Java虚拟机可用的处理器数。public long totalMemory()返回Java虚拟机中的内存总量public long freeMemory()返回Java虚拟机中的可用内存public Process exec(String command)启动某个程序并返回代表该程序的对象话不多少上代码。/** * 目标了解下Runtime的几个常见方法。 */ public class RuntimeTest { public static void main(String[] args) throws IOException, InterruptedException { // 1、public static Runtime getRuntime() 返回与当前Java应用程序关联的运行时对象。 Runtime r Runtime.getRuntime(); // 2、public void exit(int status) 终止当前运行的虚拟机,该参数用作状态代码; // 按照惯例非零状态代码表示异常终止。 // r.exit(0); // 3、public int availableProcessors(): 获取虚拟机能够使用的处理器数。 System.out.println(r.availableProcessors()); // 16 // 4、public long totalMemory() 返回Java虚拟机中的内存总量。 // 1024 1K 1024 * 1024 1M System.out.println(r.totalMemory()/1024.0/1024.0 MB); // 5、public long freeMemory() 返回Java虚拟机中的可用内存量 System.out.println(r.freeMemory()/1024.0/1024.0 MB); // 6、public Process exec(String command) 启动某个程序并返回代表该程序的对象。 Process p r.exec(D:\\Software\\Tencent\\TIM\\Bin\\TIM.exe); Thread.sleep(10000); // 让程序在这里暂停5s后继续往下走 p.destroy(); // 销毁关闭程序 } }二、BigDecimal类(重点)各位同学接下来我们学习的这个类叫BigDecimal至于它是干什么用的我们先不说。我们先看一段代码看这个代码有什么问题再说BigDeimal这个类是干什么用的这样会更好理解一些。public class Test { public static void main(String[] args) { // 浮点型运算时, 直接 - * / 可能会出现运算结果失真 System.out.println(0.1 0.2); System.out.println(1.0 - 0.32); System.out.println(1.015 * 100); System.out.println(1.301 / 100); } }运行以上代码我们会发现结果并和我们想看到的不太一样。如下图所示为了解决计算精度损失的问题Java给我们提供了BigDecimal类它提供了一些方法可以对数据进行四则运算而且不丢失精度同时还可以保留指定的小数位。BigDecima的常见构造器构造器说明public BigDecimal(double val) 注意不推荐使用这个将 double转换为 BigDecimalpublic BigDecimal(String val)把String转成BigDecimal底层计算的原理: 在BigDecimal内部它使用一个整数数组来存储数值的每一位。通常情况下数组的每个元素表示一组十进制数的位数例如数组的第一个元素表示最低位第二个元素表示十位以此类推。每个数组元素都是一个32位整数即可以存储0到2^32-1之间的数值。 在进行数值的运算时BigDecimal会根据操作的类型和需要的精度对两个数值进行相应的运算例如加法、减法、乘法和除法。运算的过程中它会对两个数值的符号进行处理并按照数学规则进行运算。对于除法运算BigDecimal会通过精确的算法进行计算避免了浮点数除法可能产生的精度损失。BigDecima的常用方法方法名说明public static BigDecimal valueOf(double val)转换一个 double成 BigDecimalpublic BigDecimal add(BigDecimal b)加法public BigDecimal subtract(BigDecimal b)减法public BigDecimal multiply(BigDecimal b)乘法public BigDecimal divide(BigDecimal b)除法public BigDecimal divide (另一个BigDecimal对象精确几位舍入模式)除法、可以控制精确到小数几位public double doubleValue()将BigDecimal转换为double下面看代码演示一下public class BigDecimalTest { public static void main(String[] args) { // 浮点型运算时, 直接 - * / 可能会出现运算结果失真 double a 0.1; double b 0.2; System.out.println(a b); //0.30000000000000004 此时会导致精度失真 System.out.println(-----------------------); /** * 如何解决精度失真问题? 使用BigDecimal可以解决 */ // BigDecimal a1 new BigDecimal(Double.toString(a)); // BigDecimal b1 new BigDecimal(Double.toString(b)); /** * 简单写法: * 推荐用以下方式:把小数转换成字符串再得到BigDecimal对象来使用(更简洁) */ BigDecimal a1 BigDecimal.valueOf(a); BigDecimal b1 BigDecimal.valueOf(b); System.out.println(a1.add(b1)); // 加 System.out.println(a1.subtract(b1)); // 减 System.out.println(a1.multiply(b1)); // 乘 System.out.println(a1.divide(b1)); // 除 // 除法还可以设置精度保留几位 BigDecimal d1 BigDecimal.valueOf(0.1); BigDecimal d2 BigDecimal.valueOf(0.3); BigDecimal d3 d1.divide(d2, 2, RoundingMode.HALF_UP); // 0.33 System.out.println(d3); System.out.println(-----------------------); // 把BigDecimal对象又转换成double类型的数据 double v d1.doubleValue(); System.out.println(v); } }三、Date类接下来我们学习一下Date类Java中是由这个类的对象用来表示日期或者时间。Date对象记录的时间是用毫秒值来表示的。Java语言规定1970年1月1日0时0分0秒认为是时间的起点此时记作0那么10001秒1000毫秒就表示1970年1月1日0时0分1秒依次内推。下面是Date类的构造方法和常见的成员方法利用这些API写代码尝试一下public class DateTest { public static void main(String[] args) { // 目标掌握Date日期类的使用。 // 1、创建一个Date的对象代表系统当前时间信息的。 Date d1 new Date(); System.out.println(d1); // 2、拿到时间毫秒值。 long time d1.getTime(); System.out.println(time); // 3、把时间毫秒值转换成日期对象 2s之后的时间是多少。 time 2 * 1000; Date d2 new Date(time); System.out.println(d2); // 4、直接把日期对象的时间通过setTime方法进行修改 Date d3 new Date(); d3.setTime(time); System.out.println(d3); } }四、SimpleDateFormat类各位同学前面我们打印Date对象时发现打印输出的日期格式我们并不喜欢是不是你们喜欢那种格式呢是不是像下面页面中这种格式啊接下来我们学习的SimpleDateFormat类就可以转换Date对象表示日期时间的显示格式。我们把Date对象转换为指定格式的日期字符串这个操作叫做日期格式化反过来把指定格式的日期符串转换为Date对象的操作叫做日期解析。接下来我们先演示一下日期格式化需要用到如下的几个方法注意创建SimpleDateFormat对象时在构造方法的参数位置传递日期格式而日期格式是由一些特定的字母拼接而来的。我们需要记住常用的几种日期/时间格式字母 表示含义 yyyy 年 MM 月 dd 日 HH 时 mm 分 ss 秒 SSS 毫秒 EEE 星期几 a 上午/下午 2022年12月12日 的格式是 yyyy年MM月dd日 2022-12-12 12:12:12 的格式是 yyyy-MM-dd HH:mm:ss 按照上面的格式可以任意拼接但是字母不能写错最后上代码演示一下public class SimpleDateFormatTest1 { public static void main(String[] args) throws ParseException { // 目标掌握SimpleDateFormat的使用。 // 1、准备一些时间 Date date new Date(); System.out.println(date); // 获取毫秒值 long time date.getTime(); System.out.println(time); // 2、格式化日期对象和时间 毫秒值。 SimpleDateFormat sdf new SimpleDateFormat(yyyy年MM月dd日 HH:mm:ss EEE a); String rs1 sdf.format(date); System.out.println(rs1); // 毫秒值进行时间格式化 String rs2 sdf.format(time); System.out.println(rs2); System.out.println(----------------------------------------------); // 目标掌握SimpleDateFormat解析字符串时间 成为日期对象。 String dateStr 1999-12-1 12:12:11; // 1、创建简单日期格式化对象 , 指定的时间格式必须与被解析的时间格式一模一样否则程序会出bug. SimpleDateFormat sdf2 new SimpleDateFormat(yyyy-MM-dd HH:mm:ss); Date d2 sdf2.parse(dateStr); System.out.println(d2); } }public class SimpleDateFormatDemo { public static void main(String[] args) throws ParseException { // 目标完成秒杀案例。 // 1、把开始时间、结束时间、小贾下单时间、小皮下单时间拿到程序中来。 String start 2023年11月11日 0:0:0; String end 2023年11月11日 0:10:0; String xj 2023年11月11日 0:01:18; String xp 2023年11月11日 0:10:57; // 2、把字符串的时间解析成日期对象。 SimpleDateFormat sdf new SimpleDateFormat(yyyy年MM月dd日 HH:mm:ss); Date startDt sdf.parse(start); Date endDt sdf.parse(end); Date xjDt sdf.parse(xj); Date xpDt sdf.parse(xp); // 3、开始判断小皮和小贾是否秒杀成功了。 // 把日期对象转换成时间毫秒值来判断 long startTime startDt.getTime(); long endTime endDt.getTime(); long xjTime xjDt.getTime(); long xpTime xpDt.getTime(); if(xjTime startTime xjTime endTime){ System.out.println(小贾您秒杀成功了~~); }else { System.out.println(小贾您秒杀失败了~~); } if(xpTime startTime xpTime endTime){ System.out.println(小皮您秒杀成功了~~); }else { System.out.println(小皮您秒杀失败了~~); } } }五、Calendar类学完Date类和SimpleDateFormat类之后我们再学习一个和日期相关的类它是Calendar类。Calendar类表示日历它提供了一些比Date类更好用的方法。为什么要使用Calendar类?需求将2023年09月10日 增加一个月 实现步骤: 1. 定义字符串记住 2023年09月10日 2. 把字符串时间解析成Date日期对象 3. 通过Date日期对象获取2023年9月10日的毫秒值 4. 增加一个月的毫秒值1000 * 60 * 60 * 24 * 30 5. 再格式化时间毫秒值得到结果2023年10月10日用Date类就不太好做而用Calendar就特别方便。因为Calendar类提供了方法可以直接对日历中的年、月、日、时、分、秒等进行运算。Calendar日历类的常见方法方法名说明public static Calendar getInstance()获取当前日历对象public int get(int field)获取日历中的某个信息。public final Date getTime()获取日期对象。public long getTimeInMillis()获取时间毫秒值public void set(int field,int value)修改日历的某个信息。public void add(int field,int amount)为某个信息增加/减少指定的值注意calendar是可变对象一旦修改后其对象本身表示的时间将产生变化。public class CalendarTest { public static void main(String[] args) { // 目标掌握Calendar的使用和特点。 // 1、得到系统此刻时间对应的日历对象。 Calendar now Calendar.getInstance(); // 打印系统此刻时间的全部信息 System.out.println(now); // 2、获取日历中的某个信息 // 获取年 int year now.get(Calendar.YEAR); System.out.println(year); // 获取月 int month now.get(Calendar.MONTH) 1; System.out.println(month); // 获取日 int days now.get(Calendar.DAY_OF_MONTH); System.out.println(days); // 3、拿到日历中记录的日期对象。 Date date now.getTime(); System.out.println(date); // 4、拿到时间毫秒值 long time now.getTimeInMillis(); System.out.println(time); // 5、修改日历中的某个信息 now.set(Calendar.MONTH, 11); // 修改月份成为 11 月份。 now.set(Calendar.DAY_OF_YEAR, 125); // 修改成一年中的第 125 天。 System.out.println(now); // 6、为某个信息增加或者减少多少 now.add(Calendar.DAY_OF_YEAR, 100); now.add(Calendar.DAY_OF_YEAR, -10); now.add(Calendar.DAY_OF_MONTH, 6); now.add(Calendar.HOUR, 12); System.out.println(now); } }六、为什么JDK8要新增日期类/** * 目标搞清楚为什么要用JDK 8开始新增的时间类。 */ public class Test { public static void main(String[] args) { // 传统的时间类Date、SimpleDateFormat、Calendar存在如下问题 // 1、设计不合理使用不方便很多都被淘汰了。 Date d new Date(); System.out.println(d.getYear()); // 获取的是125, 而不是现在的2025年 System.out.println(d.getYear() 1900); // Calendar也不是很合理, 因为需要去记住日历的每个字段信息 Calendar c Calendar.getInstance(); int year c.get(Calendar.YEAR); System.out.println(year); /** * 2、都是可变对象修改后会丢失最开始的时间信息。 * 比如: * Calendar.set()方法, 重新设置后当前的日期就获取不到了 * Date.setTime(time)方法, 重新设置后之前的信息就获取不到了 */ /** * 3、线程不安全。(后边知识会学习) * 了解下: 比如有很多用户会一起用时间对象, 如果其中一个人把时间修改了, * 另一个人也把时间进行了修改, 最终获取的时间是以哪个人为主, 就会产生冲突. */ /** * 4、不能精确到纳秒只能精确到毫秒。 * 1秒 1000毫秒 * 1毫秒 1000微妙 * 1微妙 1000纳秒 */ } }