JavaImprove--Lesson03--String的工具类,Math,Runtime,BigDecimal,Date
一String的工具类
String的作为字符串对象,也是使用最多的数据类型对象
所以难免有很多操作,字符串的常见操作包括:字符串拼接,字符串反转,字符串长度,字符串转换等
直接使用String类型来操作是不推荐的,因为它是不变长类型对象,效率很低,我们需要频繁的操字符串的时候就需要使用变长的字符串类
String的工具类有:StringBuilder,StringBuffer,StringJoiner
StringBuilder
在Java中,StringBuilder是一个可变的字符序列,用于构建和操作字符串。它提供了比String类更高的性能,因为它允许修改字符串内容而不需要创建新的字符串对象。
与String不同,StringBuilder对象的内容是可变的。你可以使用各种方法来修改它,例如append(), insert(), delete(), 和 replace()。
//无参构造 StringBuilder s1 = new StringBuilder(); //有参构造,初始化一些字符串数据 StringBuilder s2 = new StringBuilder("test");
append()实现字符串拼接,可以拼接任何的数据类型,最后返回拼接好的字符串:
//无参构造 StringBuilder s1 = new StringBuilder(); s1.append(1); //拼接 int 型 s1.append('a'); //拼接字符 s1.append(25.3); //拼接浮点数 s1.append("asdf"); //拼接字符串 System.out.println(s1.toString()); // 1a25.3asdf
reverse()实现字符串反转:
System.out.println(s1.toString()); // 1a25.3asd System.out.println(s1.reverse()); //fdsa3.52a1
toString()将StringBuilder对象转换为字符串输出:
String rs = s1.toString(); System.out.println(rs);// 1a25.3asdf
StringBuffer
StringBuffer和StringBuilder使用的的方式是一样的,甚至连API都是一样的
它们的不同点在于StringBuffer是基于线程安全的,而StringBuilder是线程步安全的
也就是说,当在多线程,多用户操作的系统内,使用StringBuilder是不安全的,而StringBuffer则是可以在多用户下正常工作的
//无参构造 StringBuffer s1 = new StringBuffer(); //有参构造 StringBuffer s2 = new StringBuffer("test");
append(),replace(),reverse(),toStrring()等方法和StrngBuilder是一样的
StringJoiner
StringJoiner 是 Java 中的一个类,位于 java.util 包中。它是用来将多个字符串连接成一个字符串的便捷工具
它是一个JDK8出现的工具类,它具有比StringBuilder处理更快,但是代码更简介的特点
在实现字符拼接时可以通过有参构造传入:间隔符,开始符,结束符
注意这里是间隔符,两两之间才能叫间隔符,开始符和结束符也是对应整个字符串的开始和结束
//有参构造,间隔符 StringJoiner s1 = new StringJoiner(", "); //有参构造,间隔符,开始符,结束符 StringJoiner s2 = new StringJoiner(", ","{ "," }");
add()字符串拼接:
//有参构造,间隔符 StringJoiner s1 = new StringJoiner(", "); s1.add("abc"); s1.add("xyz"); System.out.println(s1.toString()); //abc, xyz
案例:将数组中的元素转化为字符串,数据:{11,22,22},格式为:[11, 22, 33]
使用StringBuilder作答:
public static void main(String[] args) { //传入参数为匿名对象 System.out.println(ArrToString(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9})); //[ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] } public static String ArrToString(int[] arr){ //判空 if (arr == null){ return null; } StringBuilder s1 = new StringBuilder(); //拼接开始符 s1.append("[ "); for (int i = 0; i < (arr.length-1); i++) { //拼接中间元素和间隔符 s1.append(arr[i]).append(", "); } //拼接最后一个元素和结束符 s1.append(arr[arr.length-1]).append(" ]"); return s1.toString(); }
使用StringJoiner作答:
public static void main(String[] args) { //传入参数为匿名函数 System.out.println(ArrayToString(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9})); //[ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] } public static String ArrayToString(int[] arr){ if (arr == null){ return null; } //StringJoiner直接声明:间隔符,开始符,结束符 StringJoiner s1 = new StringJoiner(", ", "[ ", " ]"); for (int i = 0; i < arr.length; i++) { s1.add(String.valueOf(arr[i])); } return s1.toString(); }
二.Math,Runtime
Math是数学函数库
常用的数学函数
abs()取绝对值:
// public static double abs(double a) //取绝对值 System.out.println(Math.abs(-12.3));// 12.3
ceil()向上取整:
//public static double ceil(double a); //向上取整 System.out.println(Math.ceil(12.3)); //13.0
floor()向下取整:
//public static double floor(double a) //向下取整 System.out.println(Math.floor(12.3)); //12.0
round()四舍五入:
//public static long round(double a) //四舍五入 System.out.println(Math.round(12.3));//12
max()/min()最大最小值:
// public static int max / min (int a,int b //查找最大值或最小值 System.out.println(Math.max(12, 13)); //13
pow()求次方数:
// public static double pow(double a,double b) //取次方 System.out.println(Math.pow(2, 3)); //2的3次方 :8.0
random()取随机数:
//public static double random() //取随机数 System.out.println(Math.random()); //[0,1)
Runtime
指的是Java的JVM虚拟机的运行的一个状态类,并且是个单例类,因为运行状态只有一个
Java的Runtime
类是Java虚拟机的一部分,它提供了与运行时环境相关的各种方法和功能
需要注意的是,由于Runtime
类与底层系统紧密相关,因此在使用它时要特别小心。不正确的使用可能会导致资源泄漏、性能问题或安全风险。在大多数情况下,使用标准Java API(如System
类)提供的工具和方法更为安全和可靠。
获取Runtime对象:
// public static Runtime getRuntime() //返回与当前Java应用程序关联的运行时对象 Runtime run = Runtime.getRuntime();
终结JVM虚拟机:
//public void exit(int status) //终结当前的虚拟机运行,输入的状态码 0 表示正常结束,非 0 表示非正常结束
获取当前系统的处理器数:
//public int availableProcessors() //获取当前的的处理器数 System.out.println(run.availableProcessors());
JVM的内存总量,单位B:
//public long totalMemory() //返回Java虚拟机的内存总量 单位:B System.out.println(run.totalMemory()/1024.0/1024 + "MB");//243.5MB
JVM当前可用容量,单位B:
//public long freeMemory() //返回Java虚拟机中的可用内存量 System.out.println(run.freeMemory()/1024.0/1024 + "MB");//238.4MB
启动其它程序:
//public Process exec(String command) //启动某个程序,并返回代表此程序的对象 Process process = run.exec("D:\\Tencent\\WeChat\\WeChat.exe"); //启动微信 Thread.sleep(5000);//线程休眠5s process.destroy();//销毁进程,=》关闭微信
三.BigDecimal
在数据运算时候,尤其是对浮点数的加减乘除,都是有可能丢失精度的
因为基本类型的浮点数,double,float都是讲浮点数转为分数来计算的,如:1/2 + 1/3 + 1/4 + .... 1/n等
但是这就存在丢失精度的可能了,最简单的例子0.1 + 0.2 :
double a = 0.1; double b = 0.2; System.out.println(a + b); //0.30000000000000004
这就是基本类型的普通浮点数直接运算的问题,为了解决这个问题,Java提供了BigDecimal类来解决,解决思想是将浮点数转为字符数组来按位计算
BigDecimal 是 Java 中的一个类,用于表示和操作高精度的十进制数。
它通常用于金融和货币计算,因为它可以提供精确的小数点后的数值表示,而不会出现浮点数运算中的舍入误差。
BigDecimal有两种构造方式,
一种是构造器中传入一个浮点数
一种构造器是传入一个String类型
- 将构造器中传入一个浮点数是不推荐的做法,因为在进行运算的时候还是以浮点数double进行运算的,所以该有的精度丢失还是会有的
double a = 0.1; double b = 0.2; BigDecimal a1 = new BigDecimal(a); BigDecimal b1 = new BigDecimal(b); BigDecimal c1 = a1.add(b1); System.out.println(c1); //0.3000000000000000166533453693773481063544750213623046875
- 在构造器中传入一个String类型的数据,利用字符数组来存储,然后按位计算
double a = 0.1; double b = 0.2; BigDecimal a1 = new BigDecimal(String.valueOf(a)); BigDecimal b1 = new BigDecimal(String.valueOf(b)); BigDecimal c1 = a1.add(b1); System.out.println(c1); //0.3
如上,如果传入的是字符串的形式就不会存在精度丢失的情况了
我们可以利用DeBug来查看这些情况:
如上图:
我们的BigDecimal类是将浮点数利用字符数组存储的,包括小数点都有一个ASCII码存在字符数组里
相关的方法:
valueOf()将一个double类型的数据转换为BigDecimal类:
此方法是一个静态方法,可以直接点 出来
double a = 0.1; BigDecimal a1 = BigDecimal.valueOf(a); double b = 0.2; BigDecimal b1 = BigDecimal.valueOf(b); System.out.println(a1.add(b1));
使用valueOf()也是Java官方推荐的,并且是转为字符数组然后按位运算
add()加法:
double a = 0.1; BigDecimal a1 = BigDecimal.valueOf(a); double b = 0.2; BigDecimal b1 = BigDecimal.valueOf(b); //public BigDecimal add(BigDecimal b) //两个BigDecimal对象进行加法运算 BigDecimal c1 = a1.add(b1); System.out.println(c1);
double a = 0.1; BigDecimal a1 = BigDecimal.valueOf(a); double b = 0.2; BigDecimal b1 = BigDecimal.valueOf(b); //public BigDecimal subtract(BigDecimal b) //两个BigDecimal对象进行减法运算 BigDecimal c1 = a1.subtract(b1); System.out.println(c1);// -0.1
double a = 0.1; BigDecimal a1 = BigDecimal.valueOf(a); double b = 0.2; BigDecimal b1 = BigDecimal.valueOf(b); //public BigDecimal multiply(BigDecimal b) //两个BigDecimal对象进行乘法运算 BigDecimal c1 = a1.multiply(b1); System.out.println(c1);// 0.02
double a = 0.1; BigDecimal a1 = BigDecimal.valueOf(a); double b = 0.2; BigDecimal b1 = BigDecimal.valueOf(b); //public BigDecimal divide(BigDecimal b) //两个BigDecimal对象进行除法运算 BigDecimal c1 = a1.divide(b1); System.out.println(c1);// 0.5
doubleValue()返回为double类型:
double a = 0.1; BigDecimal a1 = BigDecimal.valueOf(a); double b = 0.2; BigDecimal b1 = BigDecimal.valueOf(b); BigDecimal c1 = a1.divide(b1); //将BigDecimal对象还原成为double类型 double c2 = c1.doubleValue(); System.out.println(c2);// 0.5
使用divide()方法时,需要注意,被计算的两个数一定要是可以有精确值的
意味着这两个数的结果不能是,无限循环小数,无限不循环小数等无限数,否则会报错(Non-terminating decimal expansion; no exact representable decimal result.)
因为BigDecimal类是用于解决精度丢失的问题的,不是解决无限数的
如果被除数一定要是无线数,就可以通过传入保留位数和舍入方式来控制
double a = 0.1; BigDecimal a1 = BigDecimal.valueOf(a); double b = 0.3; BigDecimal b1 = BigDecimal.valueOf(b); //被除数 保留两位小数 四舍五入 BigDecimal c1 = a1.divide(b1,2, RoundingMode.HALF_UP); System.out.println(c1);// 0.5
四.Date
Date代表的是系统当前的时间
Java 的 Date 类是 Java 核心库的一部分,位于 java.util 包中。它是用来表示特定的瞬时,精确到毫秒的时间。这个类经常用于日期和时间相关的操作,包括日期的获取、日期的比较以及日期的格式化。
Date类推荐的构造器有两个
无参构造:直接获得时间格式
//无参构造 Date d1 = new Date(); System.out.println(d1); //Sun Jan 07 10:18:54 CST 2024
有参构造:将时间戳转换为时间格式
//有参构造 long d2 = d1.getTime(); Date d3 = new Date(d2); System.out.println(d3); //Sun Jan 07 10:18:54 CST 2024
常用的Date对象方法:
getTime():获得当前时间对象的时间戳
//有参构造 long d2 = d1.getTime(); System.out.println(d2); //1704594144133
setTime(long str):设置时间对象的时间
//无参构造 Date d1 = new Date(); System.out.println(d1); //Sun Jan 07 10:24:58 CST 2024 //有参构造 long d2 = d1.getTime(); long tim = d2 + 5*1000; //向后加 5s d1.setTime(tim); System.out.println(d1); //Sun Jan 07 10:25:03 CST 2024
SimpleDateFormat
SimpleDateFormat 是 Java 中的一个类,属于 java.text 包。它用于日期和时间的格式化和解析,提供了以与语言环境有关的方式来格式化和解析日期的方法。
SimpleDateFormat 允许将日期转换为字符串,以及将字符串解析为日期。它提供了多种用于格式化和解析的静态方法
其中格式化时间符号:
y:年,M:月,d:日,H:时,m:分,s:秒,EEE:星期几,a:区分上下午
示例:
//获得时间对象 Date date = new Date(); //创建SimpleDateFormat对象并且传入时间格式 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss EEE a"); //.format方法实现格式化 String day = dateFormat.format(date); System.out.println(day); //2024-01-07 10:32:33 星期日 上午
注意,时间格式是可以进行字符拼接的,只要时间符号保持原位就行了,比如拼接上-年-月-日
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss EEE a"); //2024年01月07日 10:41:32 星期日 上午
parse(String str):将字符串格式的时间转换为Date类型的时间
//字符串日期 String data = "2002-11-04 12:25:31"; //格式样式 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //将字符转为Date Date parse = dateFormat.parse(data); System.out.println(parse);
注意,使用parse方法需要保证字符转时间格式和待转换的时间格式是一样的,不然会出错,且不能进行字符串拼接了
Calender
代表当前系统的日历对象
在编程中,Calendar
对象通常是指与日期和时间相关的数据结构或类。Calendar
提供了一个表示特定日期或时间的方式,并且常常用于日期和时间的计算、格式化以及解析。
在 Java 中,java.util.Calendar
是一个非常常用的 Calendar
类。它提供了一系列方法来操作日期和时间,例如添加或减去时间,获取月份、星期、日期的天数等
getInstance():
//获得日历对象。官方推荐使用静态方法,而不是使用构造器 Calendar calendar = Calendar.getInstance();
get(int n):获取日历的内容,传入的参数是Calender类的常量
//获得年份 int year = calendar.get(Calendar.YEAR); System.out.println(year); //2024 //获得月份 0~ 11 int month = calendar.get(Calendar.MONTH); System.out.println(month);//0 //获得日期 int day = calendar.get(Calendar.DAY_OF_YEAR); System.out.println(day); //7
getTime():获得时间
//获得当前日期,和Date相同 Date time = calendar.getTime(); System.out.println(time);//Sun Jan 07 11:54:33 CST 2024
getTimeInMillis():获得时间戳
//获得时间戳 long t = calendar.getTimeInMillis(); System.out.println(t);//1704599837468
set(int feild,int value):修改日历中的某个值:feild:Calender类的常量,value:修改的值
//获得当前年份 int year = calendar.get(Calendar.YEAR); System.out.println(year);//2024 //更改当前年份 calendar.set(Calendar.YEAR,2028); int year2 = calendar.get(Calendar.YEAR); System.out.println(year2);//2028
add(int feild,int amount):对某个信息增加/减少指定的值
//获得当前年份 int year = calendar.get(Calendar.YEAR); System.out.println(year);//2024 //增加10年 calendar.add(Calendar.YEAR,10); int year2 = calendar.get(Calendar.YEAR); System.out.println(year2);//2034 //减少20年 calendar.add(Calendar.YEAR,-20); int year3 = calendar.get(Calendar.YEAR); System.out.println(year3);//2014
注:calender是可变对象,一旦修改后其对象本身表示的时间也会变化(单例模式)