一、String类构成
final char[] ch;//“hello”
final修饰字符数组来保存字符串,所以String对象是不可变的(jdk1.8)
final class String implements Comparabe<String> { }
final修饰的类所以不能被继承,用到了comparable接口的compareto方法
1.toCharArray()转数组
2.equals方法进行比较
3.char c=charAt(int index);
4.字符串长度=str.length();
5.分割函数:split(); "i am a student" "student a am i"
6.String.valueOf(10);将整型10转为字符串类型
二、字符串拼接
1、字符串拼接操作原理:String+
1.字符串常量+字符串常量——>编译期优化
“hello”+“world”——>“hello world”
2.变量+字符串常量——>println(a+“结果”)
+会被解析为以下四步:
String str ="hello"; str=str+"world";
//+被解析为以下四步
StringBuilder s=new StringBuilder();
s.append(str);
s.append("world");
String str =s.toString();
2."+"连接符的效率
使用“+”连接符时,JVM会隐式创建StringBuilder对象,这种方式在大部分情况下并不会造成效率的损失,不过在进行大量循环拼接字符串时则需要注意。
String s="abc";
for(int i=0;i<10000;i++){
s+="abc";
}
//反编译后
String s="abd";
for(int i=0;i<1000;i++){
s=(new StringBuilder()).append(s).append("abc").toString();
}
这样由于大量StringBuilder创建在堆内存中,肯定会造成效率的损失,所以在这种情况下建议在循环体外创建一个StringBuilder对象调用append()方法手动拼接,运行时间将大大缩小
//循环中使用StringBuilder代替"+"连接符
StringBuilder sb = new StringBuilder("abc");
for(int i=0;i<1000;i++){
sb.append("abc");
}
sb.toString();
综上,“+”连接符对于直接相加的字符串常量效率很高,因为在编译期间便确定了它的值,也就是说形如"I"+“love”+“java”; 的字符串相加,在编译期间便被优化成了"Ilovejava"。对于间接相加(即包含字符串引用,且编译期无法确定值的),形如s1+s2+s3; 效率要比直接相加低,因为在编译期不会对引用变量进行优化。
三、String、StringBuilder和StringBuffer的区别
1.在单线程与多线程环境下
(1)在单线程环境下,优先考虑String和StringBuilder;
如果是常量+常量,优先选择String;
如果是常量+变量,并且次数少的情况下,选择String和S停Builder都可以。
如果是常量+变量,并且次数多的情况下,选择StringBuilder。
(2)在多线程环境下,选择StringBuffer(线程安全)
StringBuffer是线程安全的,StringBuilder是非线程安全的;
StringBuffer的append方法用synchronized关键字修饰,所以是线程安全的。
2.String类描述
String是不可变类,因为使用final关键字修饰字符数组来保存字符串private final char value[],可理解为常量,线程安全。
StringBuilder和StringBuffer是可变类,没有用final关键字修饰。StringBuilder实际是String的变量拼接常量的使用对象,调用了对象的.append方法;
StringBuffer同样使用.append方法进行拼接,并且用synchronized关键字修饰所以是线程安全的;
StringBuffer没有对方法进行加同步锁,所以是非线程安全的。
StringBuilder和StringBuffer区别在于是单线程还是多线程;
3.性能
每次对String类型进行改变的时候,都会生成一个新的String对象;
StringBuffer不会产生新的对象;
执行速度StringBuilder>StringBuffer>String