String与StringBuilder与StringBuffer的对比

版权声明:转载注明出处 https://blog.csdn.net/nobody_1/article/details/76684647

之前看别人总结说String/StringBuilder/StringBuffer三者的区别,总是忘记,所以今天特地抽个时间去看看源代码是咋说,毕竟自己理解才能记得住:

①String:最常用的包装类。都知道是不可变的:

	String s = new String("abc");    
	s = s + "def";
第一行代码的意思就是实例化一个String类型的对象,对象的具体内容为“abc”,指向实例化对象的引用名为 s;那么为什么要引用指向对象的具体内容而不直接用内容来代表呢?[涉及到JVM的内存模型,可以看深入理解Java虚拟机];

既然s是不可变的,那么为什么会出现第二行代码?

第二行代码的表面意思是“在引用s后追加def”,其实不然。具体咋回事,看看源码中的解释就知道了:

  

字符串连接符(+)和其他对象到字符串的转变是特有的支持;字符串连接符是通过StringBuilder(或者StringBuffer)类中的append方法实现的,字符串转变是通过Object类的toString()方法实现的。那么这句话表明什么呢?

难道是Stirng类型的对象s转变为StringBuilder类型的对象,然后进行append操作?显然不是这样的!始终坚信s引用指向的实例对象不可变这个原则就行。在内存上,"abc"和“def”已经有占有一定的内存,当两个不可变实例对象拼接只能是产生另外一个内存来存储拼接后的实例对象,那么这个实例对象的引用就是用已有的s来指向,也就是第二行代码的实际含义。

如果字符串采用这种方式来改变,将会造成内存的极大浪费,进而影响JVM的执行性能。所以Arthur van Hoff就提出了StringBuilder类。


②StringBuilder:是在jdk1.5版本中提出,是可变字符串序列。这个类被设计成在字符串缓冲区被单个线程使用的,所以没有保证同步。针对后面多线程,团队成员设计出StringBuffer类。


③StringBuffer:首次出现在jdk1.0版本,是线程安全的可变字符串序列,它与String类的区别是字符串可变,它与StringBuilder类的区别是安全的(多线程中),这也是为多线程而提出的一个类。


④最后,了解了三者之间的区别,对执行速度也是显而易见的:String < StringBuffer < (>)StringBuilder。

因为String每次都要产生新的对象,所以它的速度最慢。(注意:尽量避免采用New的方式定义String对象,直接采用String s =“”)

StringBuffer与StringBuilder两者在运算量不大时,耗时基本没区别,就连测试的99999次循环都只有2毫秒的差距。

	public static void main(String[] args) {
		String str = new String();
		StringBuilder sBuilder = new StringBuilder();
		StringBuffer sBuffer = new StringBuffer();
		long start = 0L;
		long end = 0L;
		start = System.currentTimeMillis();
		for (int i = 0; i < 99999; i++) {
			str = str + "a";
		}
		end = System.currentTimeMillis();
		System.out.println("使用string的时间是:" + (end - start) + "毫秒!");

		start = System.currentTimeMillis();
		for (int i = 0; i < 99999; i++) {
			sBuilder.append("a");
		}
		end = System.currentTimeMillis();
		System.out.println("使用StringBulider的时间是:" + (end - start) + "毫秒!");
		
		start = System.currentTimeMillis();
		for (int i = 0; i < 99999; i++) {
			sBuffer.append("a");
		}
		end = System.currentTimeMillis();
		System.out.println("使用StringBuffer的时间是:" + (end - start) + "毫秒!");
	}

结果:



有什么不对的,请指出,一起探讨。


PS:转载请注明出处,谢谢~

猜你喜欢

转载自blog.csdn.net/nobody_1/article/details/76684647