String的不可变性
什么是String的不可变性呢,即String的对象是不可变的,字符串一旦创建,内容不能再变,查看JDK文档你就会发现,String类中每一个看起来会修改String值的方法,实际上都是创建了一个新的String对象,以包含修改后字符串的内容,而最初的String对象则丝毫未动
字符串常量
请观察如下代码:
String str1=“我好帅”;
String str2=“我好帅”;
System.out.println(str1= =str2);
那么控制台输出的是true还是false呢?(提示:= =比较的是地址)
三秒钟思考
3
2
1
控制台输出的是true
不信?有图有真相
那小部分长得帅的人就会问了,为什么是true呢,这不是创建了新的字符串对象吗,那是因为Java中为了考虑效率,以“ ”括起来的字符串,只要内容相同(顺序、大小写均相同),无论在代码中出现几次JVM都只会建立一个实例,放在字符串池(String pool)中,所以str1=str2
再观察如下代码:
String str1=“我好帅”;
String str2=new String(“我好帅”);
System.out.println(str1==str2);
那么控制台输出的是true还是false呢?
三秒钟思考
3
2
1
答案是false
这时候就又会有小部分长得帅的人提问,这为什么又不相等了呢?因为有一个很关键的词:new,他的意思就是创建了新的空间,所以二者的地址就不相等啦
字符串的相关函数
String()
创建一个空字符串对象
String(String original)
用字符串直接创建新字符串对象
String (char value[])
用字符数组创建一个字符串
String(byte bytes[])
用字节数组创建一个字符串
length()
获取字符串中的字符个数
charAt(index)
返回字符串中指定下标的字符
concat(str)
拼接字符串,返回一个新字符串对象
toUpperCase
返回一个新字符串,所有字母大写
toLowerCase
返回一个新字符串,所有字母小写
trim()
返回一个新字符串,去掉两边空格
toCharArray()
将此字符串转化为一个新的字符数组
equals(str)
逐字符比较,相等返回true,不等返回false
equalsIgnoreCase(str)
忽略大小写比较
compareTo(str)
根据比较大小返回大于0,小于0,等于0的整数
compareToIgnoreCase(str)
忽略大小写比较
startsWith(prefix)
如果字符串以特定前缀开始,返回true
endsWith(suffix)
如果字符串以特定后缀结束,返回true
contains(str)
如果str是字符串的子字符串,返回true(包含)
字符串加强版
设想一下,如果有人让你拼接500000个&符号,那么我们要设置一个循环,每次循环都让字符串+="&",而没拼接一次系统都要申请一块新的内存空间,这个效率是十分低下的,为了提高效率,我们就可以使用String的升级版StringBuffer和StringBuilder,举个栗子:
long starTime=System.currentTimeMillis();
StringBuffer str1=new StringBuffer("*");
for(int i=0;i<100000;i++) {
str1.append("*");
}
long endTime=System.currentTimeMillis();
System.out.println("StringBuffer用时"+(endTime-starTime)+"ms");
StringBuilder str2=new StringBuilder("*");
starTime=System.currentTimeMillis();
for(int i=0;i<100000;i++) {
str2.append("*");
}
endTime=System.currentTimeMillis();
System.out.println("StringBuilder用时"+(endTime-starTime)+"ms");
String str3=new String("*");
starTime=System.currentTimeMillis();
for(int i=0;i<100000;i++) {
str3+="*";
}
endTime=System.currentTimeMillis();
System.out.println("+=用时"+(endTime-starTime)+"ms");