String,StringBuffer,StringBuilder详解

String,StringBuffer,StringBuilder详解String对象在赋值后,都会在字符串常量池中缓存起来,如果下次创建时,会首先判断常量池中是否已经存在缓存对象,如果有,则直接返回该引用给创建者

大家好,欢迎来到IT知识分享网。

1.String 字符串是不可变的,底层是一个final修饰的char类型的数组,如下图:

String,StringBuffer,StringBuilder详解

String对象在赋值后,都会在字符串常量池中缓存起来,如果下次创建时,会首先判断常量池中是否已经存在缓存对象,如果有,则直接返回该引用给创建者。

字符串常量池:是java内存中的一片内存空间。如下图所示:

String,StringBuffer,StringBuilder详解

通常来说,创建字符串的方式有如下两种:

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,StringBuffer,StringBuilder详解

分析上述原因:

String str2 = “Cat”; 创建时,会首先去字符串常量池中查找看有没有”Cat”字符串,如果有,则返回它的地址给str2,如果没有,则再常量池中创建一个”Cat”字符串,并将地址返回给str1

String str3 = new String(“Cat”); 创建时,会首先去字符串常量池中查找有没有”Cat”字符串,如果没有,则在字符串常量池中创建一个字符串,再在堆内存中创建一个”Cat”字符串,然后将堆内存中对应的地址返回给str3,

如下图所示:

String,StringBuffer,StringBuilder详解

(2).String str = new String(“hello”);

在内存中会创建几个对象?

答案是一个或两个,取决于字符串常量池中有没有“hello”字符串,如果有,则只需要在堆内存中创建一个,所以答案是一个,如果没有,则需要在字符串常量池和堆内存中各创建一个,所以是两个。

(3).字符串拼接

String str=”you”;

String str2 = str+”win”;

底层原理图:

String,StringBuffer,StringBuilder详解

所以,这种拼接方式的执行效率是比较低的,尽量不使用。

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");

	}

执行结果:

String,StringBuffer,StringBuilder详解

(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,StringBuffer,StringBuilder详解

String.valueOf()直接调用了底层的Integer.toString()方法,不过其中会先判空;+””由StringBuilder实现,先调用了append()方法,然后调用了toString()方法获取字符串;num.toString()直接调用了Integer.toString()方法,所以效率是:num.toString()方法最快,其次是String.valueOf(num),最后是num+””的方式

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/39225.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信