字符串处理类:java.lang.String、java.lang.StringBuffer和java.lang.StrungBuilder
共同点
都是final修饰符修饰的类,都不允许被继承。
不同点
1、 StringBuffer 是线程安全,用于 多线程 不需要额外的同步;
2、 StringBuilder 是线程不安全,效率高于StringBuffer;

使用场景:
java.lang.String, 适用于少量的字符串操作的情况;
java.lang.StringBuilder, 适用于单线程下在字符缓冲区进行大量操作的情况;
java.lang.StringBuffer, 适用多线程下在字符缓冲区进行大量操作的情况;
java.lang.String类
字符串常量池
在JVM中存在存在一个字符串常量池,用于存放特定的字符串对象,可以被共享使用。
String str1 = "abc";
String str2 = "abc";
str1和str2引用的是同一个字符串常量池里的对象,当创建一个字符串常量时,首先会在常量池中查找是否已经存在相同的字符串(通过string.equals()方法判断,如果返回true,则认为是相同的字符串);
如果存在,则直接获取其引用,不需要重新创建对象;
若不存在,则会首先创建这个对象,然后把它加入到字符串常量池中,再将它的引用返回。
由于String类是不可变类,一旦创建好后就不能修改,因此String对象可以被共享而且不会导致程序混乱。
String str3 = new String("abc");
String str4 = new String("abc");
1、str3和str4是通过new关键字创建的两个不同的对象,在内存中的地址是不同的。
2、String str3 = new String(“abc”)这条语句可以分解为两个过程:
1)创建对象
即new String(“abc”),调用String类的构造方法,传入一个字符串常量,等价于两个操作:”abc”和new String()。
如果字符串常量池中不存在”abc”,则会创建常量”abc”,并添加到常量池中;
若存在则不创建,new String()会在堆中创建一个新的对象,因此str3和str4分贝指向堆中不同的对象。
2)赋值
即String str3 = ,将一个String类型的引用赋值给str3变量,这个过程不会创建新的对象。
代码
public class StringDemo {
public static void main(String[] args) {
String str1 = "abc";
String str2 = "abc";
// true
System.out.println(str1.equals(str2));
// true
System.out.println(str1==str2);
String str3 = new String("abc");
String str4 = new String("abc");
// true
System.out.println(str1.equals(str3));
// false
System.out.println(str1==str3);
}
}
public class StringDemo2 {
public static void main(String[] args) {
// 直接引用字符串常量
String a = "直接引用字符串常量";
System.out.println("a = " + a);
// 利用构造方法实例化
String b = new String("利用构造方法实例化");
// 使用已有字符串变量实例化
String c = new String(b);
System.out.println("b = " + b);
System.out.println("c = " + c);
// 利用字符数组实例化
char [] charArray = {'t', 'i', 'm', 'e'};
String d = new String(charArray);
System.out.println("d = " + d);
char[] charArray2 = {'利', '用', '字', '符', '数', '组', '实', '例', '化'};
// 提取字符数组部分内容,从下标为4的元素开始,截取2个字符
String e = new String(charArray2, 4, 2);
System.out.println("e = " + e);
// 连接字符串
String plus = a + b + c + d + e + "!@#";
System.out.println("连接字符串 = " + plus);
// 索引字符串
char chr = plus.charAt(4);
System.out.println("字符串中索引位置为4的字符是:" + chr);
//
int charIndex = plus.indexOf("利用");
// 判断:index的值不等于-1
if (charIndex != -1) {
// 如果index不等于-1,则执行此行代码,存在
System.out.println("利用");
} else {
// 如果index等于-1,则执行此行代码,说明没有
System.out.println("利用");
}
int firstIndex = plus.indexOf("直接");
// 获取字符串中"r"第二次出现的索引位置,从第一次出现的索引位置之后开始查找
int secondIndex = plus.indexOf("直接", firstIndex + 1);
// 获取字符串中"r"第三次出现的索引位置,从第二次出现的索引位置之后开始查找
int thirdIndex = plus.indexOf("直接", secondIndex + 1);
// 输出三次获取的索引位置
System.out.println("第一次出現的索引位置是:" + firstIndex);
System.out.println("第二次出現的索引位置是:" + secondIndex);
System.out.println("第三次出現的索引位置是:" + thirdIndex);
int gIndex = plus.lastIndexOf("字符");
System.out.println("最后一次出现的位置是:" + gIndex);
// 满足0<=BeforeIndex<=13条件,在满足条件的结果集中,返回最大的数字
int BeforeIndex = plus.lastIndexOf("符", 13);
System.out.println("从索引位置13开始往回搜索,'符' 最后一次出现的位置:" + BeforeIndex);
}
}