大家好,欢迎来到IT知识分享网。
1.String 字符串是不可变的,底层是一个final修饰的char类型的数组,如下图:
String对象在赋值后,都会在字符串常量池中缓存起来,如果下次创建时,会首先判断常量池中是否已经存在缓存对象,如果有,则直接返回该引用给创建者。
字符串常量池:是java内存中的一片内存空间。如下图所示:
通常来说,创建字符串的方式有如下两种:
String str = “Cat”;
String str1 = new String(“Dog”);
根据以上信息,对下面的语句进行判断
(1) String str1=”Cat”;
String str2 = “Cat”;
String str3 = new String(“Cat”);
判断:str1== str2
str1==str3
经过验证测试如下:
分析上述原因:
String str2 = “Cat”; 创建时,会首先去字符串常量池中查找看有没有”Cat”字符串,如果有,则返回它的地址给str2,如果没有,则再常量池中创建一个”Cat”字符串,并将地址返回给str1
String str3 = new String(“Cat”); 创建时,会首先去字符串常量池中查找有没有”Cat”字符串,如果没有,则在字符串常量池中创建一个字符串,再在堆内存中创建一个”Cat”字符串,然后将堆内存中对应的地址返回给str3,
如下图所示:
(2).String str = new String(“hello”);
在内存中会创建几个对象?
答案是一个或两个,取决于字符串常量池中有没有“hello”字符串,如果有,则只需要在堆内存中创建一个,所以答案是一个,如果没有,则需要在字符串常量池和堆内存中各创建一个,所以是两个。
(3).字符串拼接
String str=”you”;
String str2 = str+”win”;
底层原理图:
所以,这种拼接方式的执行效率是比较低的,尽量不使用。
2.StringBuilder 是线程不安全的,但是执行效率比较高
3.StringBuffer 是线程安全的,但是执行效率比较低
String字符串的常用优化:
(1).split() 方法,建议使用indexOf()和subString()方法进行拆分。
(2).字符串的累加方式:
(2.1) String str = “mat”;
String str2 = str+”mat”;
(2.2)StringBuffer sb = new StringBuffer();
sb.append(“Cat”);
(2.3)StringBuilder sb = new StringBuilder()
sb.append();
针对以上三种方式,举例说明:拼接一万次的字符串”s”,打印执行时间,如下:
public static void main(String[] args) {
String str ="";
long start1 =System.currentTimeMillis();
for(int i=0;i<10000;i++){
str=str+"s";
}
long end1 =System.currentTimeMillis();
System.out.println("普通拼接一万次耗时:"+(end1-start1)+"ms");
long start2 = System.currentTimeMillis();
StringBuffer sb = new StringBuffer();
for(int i=0;i<10000;i++){
sb.append("s");
}
long end2 =System.currentTimeMillis();
System.out.println("StringBuffer拼接一万次耗时:"+(end2-start2)+"ms");
long start3 = System.currentTimeMillis();
StringBuilder strBuilder = new StringBuilder();
for(int i=0;i<10000;i++){
strBuilder.append("s");
}
long end3 =System.currentTimeMillis();
System.out.println("StringBuilder拼接一万次耗时:"+(end3-start3)+"ms");
}
执行结果:
(3).基本数据类型转换成String类型的优化方案
(3.1) Integer num = 0;
String str = num+””;
(3.2)String str = String.valueOf(num);
(3.3) String str = num.toString();
针对以上三种方式,执行十万次,看看时间消耗情况
Integer num = 0;
long start1 =System.currentTimeMillis();
for(int i=0;i<100000;i++){
String str = num+"";
}
long end1 =System.currentTimeMillis();
System.out.println("普通转换一万次耗时:"+(end1-start1)+"ms");
long start2 =System.currentTimeMillis();
for(int i=0;i<100000;i++){
String str = String.valueOf(num);
}
long end2 =System.currentTimeMillis();
System.out.println("valueOf()方法转换一万次耗时:"+(end2-start2)+"ms");
long start3 =System.currentTimeMillis();
for(int i=0;i<100000;i++){
String str = num.toString();
}
long end3 =System.currentTimeMillis();
System.out.println("toString()方法转换一万次耗时:"+(end3-start3)+"ms");
执行结果如下:
String.valueOf()直接调用了底层的Integer.toString()方法,不过其中会先判空;+””由StringBuilder实现,先调用了append()方法,然后调用了toString()方法获取字符串;num.toString()直接调用了Integer.toString()方法,所以效率是:num.toString()方法最快,其次是String.valueOf(num),最后是num+””的方式
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/39225.html