String:
- 是不可变的常量,不可变的好处是编辑器让字符串共享,实际上只有用""声明的字符串才是共享的,存放在常量池中,使用new、subString、+等操作符生成的String字符串都不是共享的。
- 字符串的值比较使用的是equals(),不能使用==,==比较的是字符串地址,如果这个字符串在常量池中,那么==比较的两个引用的地址相等
- 直接使用“”声明的字符串都存在常量池中(实现共享)
- String str1=”first”;
jvm在运行时先查找常量池中是否有该字符串,如果有则直接返回该字符串的引用给first(实现了字符串 的共享) ;否则先在常量 池中创建该字符串并返回引用。 此时只会在常量池中创建String对象,不会在堆中创建。 - String str2=new String(“second”);
该代码生成了两个String对象。因为使用了“”会现在常量池中查找是否存在second对象,没有则创建
否则不创建;在常量池创建完成后,由于使用了new,jvm会在堆中创建内容相同的String对象,并将引用
返回给str2. - String str3=”what”; String str4=str3+”a nice day”;
运行时,+ 相当于new,所以堆中会有“what a nice day”对象;常量池中会有”what” “a nice day”两个对象,而不会有”what a nice day”对象。
字符串常量,字符串长度不可变。用于存放字符的数组被声明为final的,因此只能赋值一次,不可再更改。视频里主要讲解String的内存构造,在java核心技术一书中我们知道最常用的String类方法有equals(),忽略大小写比较内容equalsIgnoreCase(),返回子串subString(),字符串拼接+,除此之外还有toCharArray()、CharAt(index)、toUpperCase()、toLowerCase()
public class StringDemo {
public static void main(String[] args) {
//String--subString()
String s = "helloWorld";
System.out.println(s.substring(0,2));
String s1 = s + " ILoveTheWorld";
int age = 18;
String s2 = s + age;
System.out.println("拼接的结果:"+s1);
System.out.println("拼接的结果:"+s2);
String s3 = "helloWorld ILoveTheWorld";
//boolean--equals()
if(s1.equals(s2)){
System.out.println("s1 s2内容一致");
}
else{
System.out.println("s1 s2内容不一致");
}
if(s1.equalsIgnoreCase(s3)){
System.out.println("s1 与s3不区分大小写的情况下内容一致");
}
//char[]--toCharArray() char--charAt()
String ss = "cscs";
char[] c = ss.toCharArray();
System.out.println(c);
System.out.println(ss.charAt(0));
//转换大小写
String xx = ss.toUpperCase();
System.out.println(xx);
System.out.println(xx.toLowerCase());
//将int、double、char、Boolean、Object等转成String 静态方法valueOf(各种类型)
int i = 0;
String zs = String.valueOf(i);
//boolean--endsWith(String)
String sss = "cs.java";
boolean b = sss.endsWith(".java");
System.out.println(b);
System.out.println(sss.concat("is Student"));
//在IO中使用的byte[] --getBytes()
byte[] by = sss.getBytes();
System.out.println(by);
}
}
StringBuffer和StringBuilder都j继承了AbstractStringBuilder,使用了模板的设计模式,查看源码可以发现,大部分的核心数据的操作都是放在父类中进行,子类中只实现了子类额外的功能。
StringBuffer:
字符串变量(Synchronized,即线程安全)。内部采用的是可变数组,不用final修饰,默认容量是16个字符,他的变长也是由于复制造成的,所以效率比String慢。如果要频繁对字符串内容进行修改,出于效率考虑最好使用 StringBuffer,如果想转成 String 类型,可以调用 StringBuffer 的 toString() 方法。Java.lang.StringBuffer 线程安全的可变字符序列。在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。可将字符串缓冲区安全地用于多个线程。它的增删改等方法中修饰符由synchronized的修饰。
构造函数:StringBuffer()和StringBuffer(String)底层存储数据的Char[]数组,初始化时,该数组的长度是16。如果构造函数有新传入字符转str,则16基础上加str.length.
字符串添加:
-->先检查内部char[]数组是否需要扩容
-->如需要扩容则进行扩容,然后将原来元数据copy到新数组中。
-->再将新添加的元数据加入到新char[]数组中
StringBuilder:
字符串变量(非线程安全)底层结构和StringBuffer实现基本一样,只是没有做同步处理。
基本原则:
- 如果要操作少量的数据用 String ;
- 单线程操作大量数据用StringBuilder ;
- 多线程操作大量数据,用StringBuffer。
StringBuffer的六种基本操作:
- append()
- length()
- insert()
- replace()
- reverse()
- toString()