常用类包括:包装类(Wrapper)、String、StringBuffer、StringBuilder、Math、Arrays、System、大数(big..)、日期类(Date、Calendar、LocalDate)
一、包装类(Wrapper)
针对八种基本数据类型相应的引用类型——包装类。
这样基本数据类型就有了类的特点,可以调用类的方法。
![](https://img-blog.csdnimg.cn/direct/256a1f92c254415d93c2a162f502b737.png)
包装类和基本数据类型的转换:
①JDK5之前手动装箱和拆箱。装箱:基本类型 -> 包装类型,反之为拆箱。
②JDK5之后(包括5)自动装箱和拆箱。
③自动装箱底层调用的是valueOf()方法,比如Integer.valueOf();
![](https://img-blog.csdnimg.cn/direct/b01c4daf95d24dfa8ef81ac42d7a86a7.png)
包装类和String互相转化:
Integer i = 10;
String s = "123";
1、包装类转String:
① String str = i + "";
② String str = i.toString();
③ String str = String.valueOf(i);
2、String转包装类:
① Integer inte = Integer.parseInt(s);
② Integer inte = new Integer(s);
Integer创建机制:
如下代码:
Integer i1 = new Integer(1);
Integer i2 = new Integer(1);
i1 == i2;//False
Integer i3 = 1;
Integer i4 = 1;
i3 == i4;//True
Integer i5 = 128;
Integer i6 = 128;
i5 == i6;//False
i1 ≠ i2:
是因为 i1 和 i2 都是 new出来的对象,二者地址肯定不一样。
i3 == i4:
i5 ≠ i6:
因为 Integer i3 = 1;在底层使用的是 IntegervalueOf(int i)。
下方是它的源码:
Integer.valueOf(i)源码:
![](https://img-blog.csdnimg.cn/direct/faa09f90c98f4724bf14feee7b62ce2c.png)
可见,如果 i 的值在IntegerCache.low(-128) 和 IntegerCache.high(127) 之间,将直接从缓存里返回,
所以在此范围内的 i 返回时,那么将返回同一个对象。所以i3 == i4.
不在此范围内,则new一个新的对象。所以 i5 ≠ i6.
二、String
1、继承实现关系图:
![](https://img-blog.csdnimg.cn/direct/fc15e79b90c14025b6df80371a03e169.png)
①实现了接口Serializable,说明该类可以序列化,最大的作用就是可以存入数据库或在网络上传输。
②实现了接口Comparable,说明该类可以排序或比较大小,按照某种规则。
详细信息:
Comparable接口作用
2、细节
1、字符串常量就是双引号括起来的字符序列,例如"123","你好"等。
2、字符串的字符使用Unicode字符编码,一个字符(大小写字母、汉字)都占两个字节。
3、String类是final,不能被其他类继承。
4、String有属性 private final char value[];用于存放字符串内容。
value是final类型的,一旦赋值之后不可以修改(
不是里面的值不可修改,是地址不可修改)。
如图:
![](https://img-blog.csdnimg.cn/direct/edc231f46fcc43bcb94e51dd158511c9.png)
之所以String类型变量可以变,是它指向的地址在变,原来的字符串(String类型对象)不变。
详细信息:
String类的值不可修改
3、String创建对象机制:
1、直接赋值:
String str = "123";
①从常量池查看是否有"123"的数据空间,如果有,直接指向。
②如果没有,重新创建,然后指向。
③str最终指向常量池中的空间地址。
2、调用构造器(构造器重载了很多):
String str = new String("123");
①现在堆中创建空间,里面维护value属性,指向常量池"123"空间。
②如果常量池有"123",直接通过value指向,没有则创建再指向。
③str最终指向堆中的空间地址。
![](https://img-blog.csdnimg.cn/direct/b1dee5e84d274abe9c8e4b78aa7f2b22.png)
例:
分析:
s1指向常量池中"123"的地址。
s2指向堆中字符串对象的地址,该对象的value属性指向常量池中"123"的地址。
所以s1 == s2 为false,因为二者指向的地址不相同。
但是s1 == s2.inturn()为true,因为二者都是指向常量池中的"123"的地址。
注意:
String.inturn()可以认为其返回值就是属性value所指向的值。
![](https://img-blog.csdnimg.cn/direct/19af53875fb946eca78e5dabc6650818.png)
4、String对象特性
1、String是一个final类,代表不可变的字符序列。
字符串是不可变的,一个字符串对象一旦被分配,其内容是不可变的。
例①:
如下代码其实创建了2个对象,先在常量池中创建"hello",然后s1指向该地址。
然后再在常量池中创建"ha",再将s1指向新的地址。
所以是创建了两个字符串常量,并不是改变"hello",只新建一个。
String s1 = "hello";
s1 = "ha";
例②:
如下,编译器会对此语句进行优化,
优化方法是判断常量对象是否有引用指向。
例如"123"和"456"只是拼接一下,各自并没有变量引用,所以不会创建这两个对象。
所以下面代码 相当于 String s2 = "123456";
只创建1个对象。
而不是:
创建3个对象,先创建"123"和"456"两个,
然后创建"123456".并将s2指向该地址。
String s2 = "123" + "456";
例③:注意比较和例②的区别
如下,因为"123"和"456"都有引用指向,所以和例②不一样。
通过下断点可以得知:
第一步,在常量池创建"123";
第二步,在常量池创建"456";
第三步 ①创建一个StringBuilder sb = new StringBuilder();
②执行sb.append("123");
③执行sb.append("456");
④String c = sb.toString();
所以最后c指向堆中一个String对象,该对象的value属性指向常量池中"123456"。
String a = "123";
String b = "456";
String c = a + b;
例④:
题目:
![](https://img-blog.csdnimg.cn/direct/75bfe4cf4cca445fb20a202fc5e8c928.png)
分析:
①如下图,现在堆中创建Test1对象。
属性str指向堆中新的String对象,该对象的value指向常量池中hsp。
属性ch指向堆中数组对象,值为java。
②调用change方法,进入change栈
change方法中str指向ex对象的str属性所指向的地址。
ch指向ex对象的ch属性所指向的地址。
然后str重新指向常量池中java。
ch[0]='h';则ch所指向的地址的值变为"hava"。
③change栈释放。
此时,ex的str属性指向没变化,ch属性中的值变化为"hava";
④所以输出:
hsp and hava
![](https://img-blog.csdnimg.cn/direct/66c0985b9fad4bccb2e61cf333778b83.png)
5、String常用方法
![](https://img-blog.csdnimg.cn/direct/b9b73a798f894605aedad0b7e9190285.png)
compareTo:
源码如下:
可见,比较两个字符串时,
先逐个比较,若不一样则返回不一样的字符差值。
若到达两个待比较字符串中较小的长度依旧都一样,
则返回两个字符串长度的差值。
![](https://img-blog.csdnimg.cn/direct/b3ef68a85ec848199830a44f922069b2.png)
三、StringBuffer
1、继承关系图
![](https://img-blog.csdnimg.cn/direct/b65d182a6797460b82e9d2124e18780d.png)
①实现了接口Serializable,说明该类可以序列化,最大的作用就是可以存入数据库或在网络上传输。
②实现了接口Comparable,说明该类可以排序或比较大小,按照某种规则。
详细信息:
Comparable接口作用
2、细节
1、在父类AbstractStringBuilder中有属性value
属性value用来存储数据,并且其不是final类型的。
因此,
其存放在堆中,因为这是一个char类型的数组。
![](https://img-blog.csdnimg.cn/direct/857309bfd6b34da287669813e1b2a4b3.png)
2、StringBuffer是final,不可以被继承。
3、String 保存的是字符串常量,每次更新其实是更改地址,效率低
StringBuffer 保存的是字符串变量,不用每次更改地址(空间不够会更新地址),直接更新内容,效率高。
4、构造器:
![](https://img-blog.csdnimg.cn/direct/de1d9ef7096142039adff00392ce38ab.png)
其中StringBuffer(String str)源码:
可见其创建了str字符串长度加16的容量的字符数组,并将str追加进去。
![](https://img-blog.csdnimg.cn/direct/7509bfbf4be640b2bd4c07029e7f6877.png)
由源码可知,当str为null时,str.length()会报错,空指针异常,与append方法不一样。
5、append方法:
如下图,当StringBuffer对象append一个空字符串时
会调用StringBuffer(str)构造函数 ->
父类AbstractStringBuilder append(String str) ->
AbstractStringBuilder appendNull(),源码如下第二张图
会直接将null转化成字符数组,并添加到StringBuffer对象当中。
![](https://img-blog.csdnimg.cn/direct/acc169ecd69249e083998f8c78d79238.png)
![](https://img-blog.csdnimg.cn/direct/ee28da52be10487cb653dce9cf54733a.png)
3、String和StringBuffer转换
1、String -> StringBuffer
①使用构造器
String str = "hello";
StringBuffer strbuf = new StringBuffer(str);//返回值才是StringBuffer类型,对String str自身没有影响。
②使用apend方法
String str = "hello";
StringBuffer strbuf = new StringBuffer();
strbuf = strbuf.append(str);
2、StringBuffer -> String
①使用构造器
StringBuffer strbuf = new StringBuffer("hello");
String str = new String(strbuf);
②使用toString()方法
StringBuffer strbuf = new StringBuffer("hello");
String str = strbuf.toString();
4、StringBuffer方法
![](https://img-blog.csdnimg.cn/direct/f2572e4aea7043548829704e892a90e4.png)
四、StringBuilder
1、继承关系图
![](https://img-blog.csdnimg.cn/direct/5e1cee401dc04d9285e524bd58e03fec.png)
可见和StringBuffer一模一样。
StringBuilfer是一个可变的字符序列。
其提供一个与StringBuffer兼容的API,但不保证同步。
该类被设计用作StringBuffer的一个
简易替换,用在字符串缓冲区被单个字符使用的情况。(此类不是线程安全的)
建议优先使用这个类,因为在多数实现中,他比StringBuffer快。
原因如图:
可见StringBuffer有关键字synchronized进行加锁了。
![](https://img-blog.csdnimg.cn/direct/b0dd55dcbb5840c9ab81c09f1ecf0aff.png)
![](https://img-blog.csdnimg.cn/direct/fb4ef8757d5d47cc886ea37135b9ec94.png)
2、细节
1、StringBuilder上的主要操作是 append 和 insert 方法,该类重载了此方法,可接收任意Java内置的对象或基本数据。
2、此类也是final类,不能被继承。
3、此类的数据也是存放在父类的value属性中,也是在堆中,和StringBuffer一致。
3、String、StringBuffer、Stringbuilder三者比较:
![](https://img-blog.csdnimg.cn/direct/f2e8d933d689415bab8078be97d2f475.png)
![](https://img-blog.csdnimg.cn/direct/697825e6c93e494f85032f8e7c95d116.png)
五、Math、Arrays、System、大数(big..)
1、Math
Math类包含用于执行基本数学运算的方法,如指数、对数、平方根和三角函数。
Math类的方法全部都静态。
常用方法:
![](https://img-blog.csdnimg.cn/direct/78749cf46ed04bbea8b1266008647f1d.png)
2、Arrays
包含了一系列静态方法,用于管理和操作数组(例如排序和搜索)。
常用方法:
1、toString()
返回数组的字符串形式。
源码如下:
分析可知,创建一个StringBuilder对象,加一个 [ ,
之后将数组的每个字符拼接到该对象,最后再加一个 ] ,
最后将StringBuilder转为String后返回。
![](https://img-blog.csdnimg.cn/direct/98524f12ff2f4193af63f7561d2f92ad.png)
2、sort()
排序
①自然排序
②定制排序
两个参数,一个是待比较的数组,另一个为接口Comparater的实现类(使用匿名内部类)
该接口需要实现compare方法,用于定制比较规则。
如图为调用该定制方法的时机,可见返回值大于0或小于0,将会影响排序方法。
![](https://img-blog.csdnimg.cn/direct/cc263fe32601437baa3c8bba6aa2cb12.png)
3、binarySearch()
通过二分查找法进行查找,要求必须排好序。
该方法返回值:
源码中为 return -(low + 1); // key not found.
low为其应该在的位置:
比如在数组{1,2,5,8}中查找9,发现找不到
则其应该在8的右边,即下标为4的位置,则返回-(4 + 1) = -5
4、copyOf()
拷贝传入的数组,有两个参数,第一个为待拷贝的参数,第二个参数为拷贝的长度。
若长度超出待拷贝的数组,则对应位置为 null.
若长度为负数,会抛出异常。
5、fill()
数组元素填充,就是使用第二个参数的值替换原数组中的数值。
6、equals()
比较两个数组内容是否完全一样。
7、asList()
将一组值,转化为list。
3、System
常用方法:
1、exit()
退出当前程序。
2、arraycopy()
复制数组元素,比较适合底层调用,一般使用Arrays.copyOf()完成数组复制。
3、currentTimeMillens()
返回当前时间距离1970年一月一日的毫秒数
4、gc()
运行垃圾回收机制。
4、大数
1、BigInteger整数
进行加减乘除不能直接使用+-*/,需要使用相应的方法(add、sunttract.....)。
2、BigDecimal小数
对其进行加减乘除与整数类似。
注意,进行除法时,当除不尽即无限循环小数则会抛出异常。解决方法:在方法参数中增加一个精度。
六、日期类(Date、Calendar、LocalDate)
第一代:Date
精确到毫秒,代表特定瞬间。
这是Java.Util包里的,不是sql.date
配套SimpleDateFormat类:
SimpleDateFormat 是一个以与语言环境有关的方式来格式化和解析日期的具体类。
它允许进行格式化(日期 -> 文本)、解析(文本 -> 日期)和规范化。
![](https://img-blog.csdnimg.cn/direct/7d7133ae3d044cff8652a553d3829886.png)
方法:
构造器:
Date();获取当前时间,返回字符串,英文
Date(long);将long变量转化为对应的时间,返回值和上面一样。
第二代:Calendar
Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。
瞬间可用毫秒值来表示,它是距历元(即格林威治标准时间 1970 年 1 月 1 日的 00:00:00.000,格里高利历)的偏移量。
也是java.util包里的。
类定义:
public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>{}
方法:
其为抽象类,且其构造器为protected,可以使用getInstance()来获取其实例,即模板设计模式的应用。
Calendar没有提供对应的格式化类,需要自己组合。
第三代:LocalDate
![](https://img-blog.csdnimg.cn/direct/915c29fb1471464490872b08edde1c6b.png)
在JDK1.8之后加入:
![](https://img-blog.csdnimg.cn/direct/40cdd08577a94853940998a02c218381.png)
可以使用DateTimeFormatter来格式化日期形式。
![](https://img-blog.csdnimg.cn/direct/3a22307b238e47f59d4a76b0b49f606a.png)
.......
Instant: s
时间戳