String和StringBuilder效率不同的原理

在做实验的时候,中间有一个任务为一个图的toString.,用来打印每条边每个点的信息。

其中用到了字符串的链接 我当时用的是String 的 “+”操作,

但是图怎么也无法输出,因为有三十多万条边,在大量的字符串的拼接的时候,“+”特别耗时间和内存。

然后我通过网上查找,选择用StringBuilder的方法解决了这个问题。

StringBuilder str = new StringBuilder();
str.append("lalalallal");
for(int i=0;i<5;i++)
    str.append("lalalallal");
System.out.println(str);

但是当时也没有仔细想原理是什么,而后来复习到mutable(可变数据类型)和immutable(不可变数据类型)的时候才仔细思考了这个问题,String和StringBuilder正好是它们的典型代表。

String是immutable的变量,一旦被创建,它的值就不能被改变。注意:改变一个变量是将该变量指向另一个值的存储空间,二改变一个变量的值是将该变量当前指向的值的存储空间写入一个新的值。

通过分析snapshot diagram我们发现,当string "+"的时候,是新建了一个String空间然后将原来变量的指向这个空间。原来的String被废弃只能等待着被垃圾回收。又通过后来学习的垃圾回收的机制我们知道这是非常浪费资源的,当然也有其安全性。

而StringBuilder则是直接修改,所以执行起来很快。

其实这只是区别的一部分,因为这种机制的不同还带来了很多很多潜在的bug

比如:

List<String> list =new LinkedList<>();
String s1 = new String("aaa");
list.add(s1);
System.out.println(list.contains(s1));//true
s1=s1.concat("q");
System.out.println(list.contains(s1));//false

 奇怪的是,把s1加入到list之后,修改了s1,此时s1就不包含在list里面了

通过snapshot diagram可以看见这种现象的原因。List是直接指向元素所在的空间,当修s1之后,s1的引用改变,此时s1指向的空间也已经改变,不再是从前的s1了。

 

比如:

		String s="ab";
		String t=s;
		s=s+"c";
		System.out.println(t);//ab

 因为虽然t指向了s,但是s改变之后,t指向的值并没有改变,因为此时s是重新指向了新的区域。

因此,我们在选择合适的类型的时候,要仔细考虑的有安全、效率、还要多个引用带来的潜在的bug

原文地址:https://www.cnblogs.com/blairwaldorf/p/9191339.html

时间: 2024-11-08 20:40:08

String和StringBuilder效率不同的原理的相关文章

[转] 深入探究 String 与 StringBuilder 内部原理

转自:深入探究 String 与 StringBuilder 内部原理 System.String 类型一直是我们不断讨论的话题,它是一个用于对字符串进行存储和操作的这么一个类型. System.String 也是 C# 基础类型中唯一的引用类型.但是,它却具有很多值类型的特点. 我们来看一段简单的代码: 1 string text = "White"; 2 string temp = text; 3 temp = "Black"; 4 Console.WriteL

java StringBuffer,StringBuilder,String自身连接效率对比

当我们仅仅需要a+b 的时候,两个字符串链接任何方法的效率基本一样,都在0.0001毫秒内就可以完成.不过如果需要1万次,10000万次,就会发现string自身的join速度显著下降 package com.java.lang; public class StringTest { int MAX = 10000; //1万次累加 public String Buffer(){ StringBuffer sb = new StringBuffer(); for(int i = 0; i < MA

java中String与StringBuilder的区别

本篇文章介绍了,java中String与StringBuilder的区别. 相信大家对 String 和 StringBuffer 的区别也已经很了解了,但是估计还是会有很多同志对这两个类的工作原理有些不清楚的地方,今天我在这里重新把这个概念给大家复习一下,顺便牵出 J2SE 5.0 里面带来的一个新的字符操作的类—— StringBuilder (先别忙着扔我砖头,我还算清醒,我这里说的不是 C #, Java 也有 StringBuilder 类).那么这个 StringBuilder 和

string、stringbuilder、stringbuffer区别

java中String.StringBuffer.StringBuilder是编程中经常使用的字符串类,他们之间的区别也是经常在面试中会问到的问题.现在总结一下,看看他们的不同与相同.1.可变与不可变 String类中使用字符数组保存字符串,如下就是,因为有“final”修饰符,所以可以知道string对象是不可变的. private final char value[]; StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在Abstrac

String StrigBuffer StringBuilder 浅解

1.String是最基本的字符串类,用于表示字符串. 特点:对象内容不可变,但可以通过指向不同的对象来“表示”不同的内容. 使用场景:如果不涉及到内容改变,可以使用String. 注意:如果想将String作为输出型参数,抱歉,做不到. 方法返回后,内容还是没有赋上值.具体原因就得追究到内存原理上了.此处不再叙述. 2.StringBuffer:针对String要改变内容必须指向别的对象的缺陷而设计,StringBuffer可以直接改变其内容,不需要指向别的对象. 特点:内容可改变(通过appe

6-探秘Java中的String、StringBuilder以及StringBuffer

相信String这个类是Java中使用得最频繁的类之一,并且又是各大公司面试喜欢问到的地方,今天就来和大家一起学习一下String.StringBuilder和StringBuffer这几个类,分析它们的异同点以及了解各个类适用的场景.下面是本文的目录大纲: 一.你了解String类吗? 二.深入理解String.StringBuffer.StringBuilder 三.不同场景下三个类的性能测试 四.常见的关于String.StringBuffer的面试题(辟谣网上流传的一些曲解String类

Java字符串的String、StringBuilder、StringBuffer三者特性详解

一.不可变String类型 字符串是计算机程序设计中的,最常见行为,Java的字符串操作最主要的类是String,并且String对象是不可变的(Immutable),即对象一旦创建在内存中,那么它的内容就不再改变.虽然String类中提供很多方法看起来像是可以修改String对象,比如trim().subString()等等,但是实际上它们并没有改变原来的字符串对象,这些方法传递的只是引用的一个拷贝,所以重新创建了一个String类型的对象,并且有了新的引用. 例如下面一段代码可以说明Stri

String和StringBuilder、StringBuffer的区别

String和StringBuilder.StringBuffer的区别?     Java平台提供了两种类型的字符串:String和StringBuffer/StringBuilder,它们可以储存和操作字符串.其中String是只读字符串,也就意味着String引用的字符串内容是不能被改变的.而StringBuffer/StringBuilder类表示的字符串对象可以直接进行修改.StringBuilder是Java 5中引入的,它和StringBuffer的方法完全相同,区别在于它是在单线

转:String StringBuffer StringBuilder区别

转自:http://www.iteye.com/topic/522167 作者:每次上网冲杯Java时,都能看到关于String无休无止的争论.还是觉得有必要让这个讨厌又很可爱的String美眉,赤裸裸的站在我们这些Java色狼面前了.嘿嘿.... 众所周知,String是由字符组成的串,在程序中使用频率很高.Java中的String是一个类,而并非基本数据类型. 不过她却不是普通的类哦!!! [镜头1] String对象的创建       1.关于类对象的创建,很普通的一种方式就是利用构造器,