C# string 和 stringbuilder
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# string 和 stringbuilder相关的知识,希望对你有一定的参考价值。
请大家帮帮,我没有搞懂 string 和 stringBuilder
请大家 告诉我
什么是string ,string的工作原理,以及 什么是stringBuilder 和 stringBuider的工作原理 ,先谢谢大家了
在没有字符串池的情况下,比如用户定了
string a = "China";
那么相当于内存中有一块地方存储了China这个字符串
然后有定义了
string b = "China";
那么相当于内存中另一个地方又存储了China字符串,这不是重复了吗?一两个字符还没关系,但是在程序中,用到字符串的地方是很多的,特别有的地方需要用到大的文本,比如论文,字符串拼接什么的,这就会使内存大量消耗在了字符串的存储上,怎么办呢?所以就有了字符串池
程序一开始,字符串池是空的,如果用户有
string a = "China";
假设这相当于内存中的ACEF0002地址存储了China,
那么这个地址就会添加到字符串池,或者叫字符串地址列表中,
当用户定义string b = "China";时,编译器首先会去字符串池寻找是否有这个字符串,如果有,则证明该串之前曾用过,内存中已经有了,则直接让b指向ACEF0002,
同样,如果有定义
string c = "China";那么他同样会指向ACEF0002,也就是说,内存中始终只存储一次,这样就有效节省了内存资源。
除非这次遇到一个字符串池中没有的字符串,如定义
string z = "Chinese";
这时编译器发现字符串池中没有Chinese这个东西,因此他才会重新开辟一块空间来存储。
简单的说,字符串池好似一个地址集合,他存储了所有用户已经使用过的字符串地址,一旦发现新字符串在其中已经存在了,就直接用,否则才开辟新空间存储。
stringbuilder是一个用来拼接字符串的类,假设不用他,我们从键盘上输入5个字符来完成单子的拼接
1 string a = "";
2 a += scan.nextline();
3 a += scan.nextline();
4 a += scan.nextline();
5 a += scan.nextline();
6 a += scan.nextline();
以上代码执行后,五次输入分别输入"C","h","i","n","a",那么当第2行执行完后,字符串池如下
""
"C"
第3行执行完后,字符串池如下
""
"C"
"Ch"
第4行执行完后,字符串池如下
""
"C"
"Ch"
"Chi"
以此类推,也就是说,每次在原有的字符串后添加一个新字符,那么新的字符串必然是第一次出现,这就会导致字符串池中存储每一次拼接的过程,其实我们知道,我们要的只是最后的字符串。这个问题就要用到stringbuilder来解决。
StringBuilder sb = new StringBuilder();
此时sb的内容为"",
sb.append(scan.nextline());
sb.append(scan.nextline());
sb.append(scan.nextline());
sb.append(scan.nextline());
sb.append(scan.nextline());
执行以上五行语句时,依次输入"C","h","i","n","a",但是中间产生的"Ch","Chi"等字符串不会在字符串池中存放,也就是说,字符串池只对真正意义上的字符串String类起作用,系统不会为StringBuilder类型对象的每一次变化去重新开辟空间存储。
当5行语句执行完以后,你只需要这样做:
string str = sb.toString();
这样,只有最后的"China"才成为了一个字符串的实例,在拼接过程中间产生的那些没有用处的字符串不会占资源
因为没有每次申请空间去存字符串,因此stringbuilder拼接字符串的速度不尽快,而且节省资源,我曾经做过测试,如下代码:
int n = 90000;
string a = "";
StringBuilder b = new StringBuilder();
for(int i=0;i<n;i++)
b.append("a");
Console.write(b.toString());
速度很快,如果将循环中的语句改为a+="a";则慢的不行,而且如果用stringbulder,n的值最高可以达到千万,而如果用string+=的方法,1百万就会定住不动,我也不知道是因为内存满了还是速度慢了
所以总结的说,如果程序涉及不到很多的字符串拼接,那么用string也无妨,毕竟现在的机器都很强了。
如果考虑到性能和执行效率问题,一般超过5次以上的字符串拼接,建议用sb类。如果你是写服务器,则要特别注意,因为服务器长期不关机,也就意味着内存长期不刷新,如果不注意资源的释放,很可能到后期就会变慢你还不知道是什么原因,用debug软件一看才知道,里面存的都是字符串,那能够不慢吗? 参考技术A string是String对象的别名.String对象是不可改变的。每次使用 System.String 类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间。在需要对字符串执行重复修改的情况下,与创建新的 String 对象相关的系统开销可能会非常昂贵。如果要修改字符串而不创建新的对象,则可以使用 System.Text.StringBuilder类,它不会创建新的对像,而是对原。StringBuilder对象直接进行修改,所以系统开销不会增长太多.
具体使用中记住一点就行,需要做大量修改的字符串用StringBuilder类,不多变的或不变的用string.本回答被提问者采纳 参考技术B String 表示文本,即一系列 Unicode 字符。
字符串是 Unicode 字符的有序集合,用于表示文本。String 对象是 System.Char 对象的有序集合,用于表示字符串。String 对象的值是该有序集合的内容,并且该值是不可变的。
String 对象称为不可变的(只读),因为一旦创建了该对象,就不能修改该对象的值。看来似乎修改了 String 对象的方法实际上是返回一个包含修改内容的新 String 对象。
StringBuilder 类 表示可变字符字符串。无法继承此类。
此类表示值为可变字符序列的类似字符串的对象。之所以说值是可变的,是因为在通过追加、移除、替换或插入字符而创建它后可以对它进行修改。
大多数修改此类的实例的方法都返回对同一实例的引用。由于返回的是对实例的引用,因此可以调用该引用的方法或属性。如果想要编写将连续操作依次连接起来的单个语句,这将很方便。
StringBuilder 的容量是实例在任何给定时间可存储的最大字符数,并且大于或等于实例值的字符串表示形式的长度。容量可通过 Capacity 属性或 EnsureCapacity 方法来增加或减少,但它不能小于 Length 属性的值。
如果在初始化 StringBuilder 的实例时没有指定容量或最大容量,则使用特定于实现的默认值。 参考技术C string是引用类型 而且是常量,也就是不能改变,所有字符串类型都放在一个常量字符串池中
由于字符串不能被更改,所以每次赋值都是重新申请内存区并建立字符串
如果要频繁赋值就会导致大量看似重复的操作(申请新区域-建立对象-释放掉上一个字符串,当然实际操作会更复杂),这样CPU就做了很多"没用"的工作
而StringBuilder可以在创建字符串对象的时候先检查常量字符串池中是否存在,如果存在就直接使用已存在的,否则就新建一个字符串,检查存不存在的速度远比建立一个新对象的速度快,CPU也可以有更多的时间做其他工作,其实stringbuilder内部就是一个链表结构 参考技术D String 是char数组的另外一种形式,String本身是引用类型的,在定义特的类中是有final来修饰的,也就是说是不能被继承的,也不能被修改。
StringBuilder比String好的地方在于,她初始化的时候分配了一个相对大的空间,如果新加一个对象空间不够的话,会再分配一个是原来2倍大小的一个空间,然后把原来空间的数据复制到新的空间,这个过程是有损性能的
都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间。
修改StringBuilder时,在达到容量之前,它不会为其自己重新分配空间。当达到容量时,将自动分配新的空间且容量翻倍。
以上是关于C# string 和 stringbuilder的主要内容,如果未能解决你的问题,请参考以下文章