String
我们可以通过他的源码发现String是不可变的字符数组,由final修饰的char数组,也就是说我们每次赋值它都会重新创建一个数组,然后将值分成一个个的char类型存入数组中,因此它更像是一个包装类。
但当我们赋值时,两次相同的值并不会改变内存地址,而不同的值则会改变内存地址。这是因为这是一次引用传递,当我们存第一次赋值时会把值加载到堆内存的常量池中,当我们第二次赋值相同时可以在常量池中找到并将内存地址赋予,赋予不同的值时在常量池中找不到则会重新开拓内存并赋予新地址。
public static void main(String[] args) {
String str="abc";
System.out.println(System.identityHashCode(str));
str="abc";
System.out.println(System.identityHashCode(str));
str="cba";
System.out.println(System.identityHashCode(str));
}
String的比较方式可以通过equals进行比较,我们都知道==是比较内存地址的,而在所有类的父类Object中equals方法默认是==(也就是比较内存地址的),但是String中重写了该方法,因此可以进行值的比较。
1.如果地址值相等则值必定相等直接返回true;
2.比较anObject是否是String的实例
3.将实例的长度与赋值对象的长度进行比较
4.最后是将每个字符相互比较
String的排序方法,通过compareTo方法进行大小比较,然后可进行排序,如果返回负数则被比较数比比较数小,正则相反(str[被比较数].compareTo("asdf"[比较数]))
1.通过Math.min(len1, len2)比较长度返回长度小的值
2.如果是最小值是负数或0则直接进行长度运算
3.如果最小值是正数则进行ASCII运算,先比较ASCII是否相同,不同则进行减运算
isEmpty方法可以进行对字符串对象判空
lastIndexOf方法返回指定字符最后一次出现在指定字符串中的索引位置。如果未找到该字符则返回 -1.
字符串截取substring,有两个重载方法
1.从哪里开始截取如substring(1),从下标1开始截取,包含下标为1的字符
2.从哪里开始截取,从哪里结束substring(1, 2),从下标1开始截取,包含下标为1的字符,在下标2结束,不包括下标2的字符
StringBuilder
StringBuilder继承了AbstractStringBuilder,并且它存储字符是直接使用父类的数组,是可变的字符数组。
StringBuilder进行字符串拼接可拼接多种类型数据
StringBuffer
与StringBuilder一样StringBuffer同样继承了AbstractStringBuilder,并且它存储字符是直接使用父类的数组,其构造和存储方式底层是一样的,但StringBuffer会加载缓存,是可变的字符数组。并且StringBuffer的方法都是线程安全的都加有synchronized同步方法。其拼接字符方式也是相同的。