一、String
-
String
是一个final
类,不可被继承。 -
字符串是常量,用双引号引起来表示。他们的值在创建后不能更改。
-
String
实现了两个接口:Serializable
和Comparable
.前者表示字符串是支持序列化的,后者表示String
可以比较大小。 -
String
内部定义了final char[] value
用于存储字符串数据。 -
String代表不可变的字符序列,体现在以下三点:
//1. 当对字符串重新赋值时,需要重新指定内存区域赋值,不能使用原有的value进行赋值。
String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2);//"=="比较的是S1与S2的地址值,true。
s1 = "hello";
System.out.println(s1 == s2);//false
//通过字面量的方式(区别于new())给一个字符串赋值,此时的字符串值声明在字符串常量池中,
//字符串常量池中是不会存储相同内容的字符串的。
//2. 当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能在原有的value进行赋值
String s3 = "abc";
s3 += "def";
System.out.println(s3);//abcdef
System.out.println(s2);//abc
//3. 当调用String的replace方法修改指定的字符串时,也需要重新指定内存区域赋值,不能在原有的value进行赋值
String s4 = "abc";
String s5 = replace('a','m');
System.out.println(s4);//abc
System.out.println(s5);//mbc
String
的实例化方式:
public void test(){
//1.通过字面量定义的方式:此时字符串值声明在方法区的字符串常量池中
String s1 = "abc";
String s2 = "abc";
//2.通过new + 构造器的方式:此时的s3和s4保存的地址值,是数据在堆空间中开辟空间以后对应的地址值
String s3 = new String("abc");
String s4 = new String("abc");
System.out.println(s1 == s2);//true
System.out.println(s1 == s3);//false
System.out.println(s3 == s4);//false
//字符串常量存储在字符串常量池中,目的是共享,字符串非常量对象存储在堆中
//String s3 = new String("abc");这行代码在内存中创建了两个对象
//一个是堆空间中的new结构,另一个是char[]对应的常量池中的数据"abc"
}
String
不同拼接操作的对比:
//1.常量与常量的拼接结果在常量池,且常量池不会存在相同结果的常量
//2.只要其中有一个是变量,结果就在堆中
//3.如果拼接的结果调用intern()方法,结果就在常量池中
String s1 = "ABC";
String s2 = "abc";
String s3 = "ABCabc";
String s4 = "ABC" + "abc";
String s5 = s1 + "abc";
String s6 = "ABC" + s2;
String s7 = s1 + s2;
String s8 = (s1 + s2).intern();
System.out.println(s3 == s4);//true
System.out.println(s3 == s5);//false
System.out.println(s5 == s6);//false
System.out.println(s3 == s7);//false
System.out.println(s3 == s8);//true
String
类的常用方法:
int length();//返回字符串的长度
char charAt(int index);//返回某索引处的字符
boolean isEmpty();//判断是否为空字符
String toLowerCase(String str);//转小写
String toUpperCase(String str);//转大写
String trim();//返回字符串的副本,忽略前导空白和尾部空白
boolean equals();//比较字符串内容是否相同,注意与”==“的区别
boolean equalsIgnoreCase();//忽略大小写进行比较
String substring(int beginIndex);//返回一个新字符串,从原字符串beginIndex的位置开始截取
String substring(int beginIndex,int endIndex);
//返回一个新字符串,从beginIndex的位置开始到endIndex,左闭右开,不包含endIndex
String cancat(String str);//等价于”+’;
int compareTo(String anotherString);
//根据ASCⅡ比较字符串大小,看结果正负,涉及到字符串排序
String
与Char[]
之间的转换
//string--->char[]
toCharArray();
//char[]--->String,调用String的构造器
String str = new String(arr);
二、StringBuffer、StringBuilder的使用
String
、StringBuffer
、StringBuilder
三者的异同
String
:不可变的字符序列;底层使用char[]
存储。StringBuffer
:可变的字符序列;线程安全的,效率低;底层使用char[]
存储。StringBuild
:可变的字符序列;线程不安全的,效率高;底层使用char[]
存储。
- 源码分析:
String str = new String();//char[] value = new char[0]
String str = new String("abc");//char[] value = new char[]{'a','b','c'}
StringBuffer sb1 = new StringBuffer();//char[] value = new char[16],底层创建了一个长度为16的数组
sb1.append('a');//value[0]='a';
sb1.append('b');//value[1]='b';
StringBuffer sb2 = new StringBuffer("abc");//char[] value = new char["abc".length()+16]
System.out.println(sb2.length());//3