注:这篇文章基本是《C#高级编程》(第七版)第九章的学习笔记。

众所周知,C#中处理字符串通常用的都是string,它其实是.NET基础类System.String类的映射。注意一个是小写一个是大写。我觉得这种设计可能是为了在使用基础功能时让代码看起来就像在使用C风格的字符串。

String类功能强大,但是有一个问题:重复修改一个string实例,效率会很低。原因是,string对象在初始化之后就不可变了,修改string对象的方法实际上是创建新的实例。例如:

string greetingText = "First message, ";
greetingText += "Second message";

这段代码实际上做的事情是:首先,创建一个string对象,并将它初始化为文本"First message, "。然后在把对象的引用赋值给变量greetingText。第二句则创建了一个新的string对象,然后将其初始化为两个字符串连接的结果,最后将变量greetingText赋值为这个新对象的引用。这样一来,greetingText原来所引用的对象就没有被任何变量引用了,它将被垃圾收集机制销毁掉。

这种情况看起来还好,仅仅是多创建了一个对象而已。但考虑下面的情况:

把字符串中的每个字符都用其在字母表中的后一个字符来代替。

使用string的Replace方法最简单:

for (int i = 'z'; i >= 'a'; i--)
{
char old1 = (char)i;
char new1 = (char)(i+);
greetingText = greetingText.Replace(old1, new1);
}

简便起见,只写了转换小写字符的代码,也没有考虑字符'z'的情况。因此'z'会被替换为'{'。

问题来了:假如greetingText含有从'a'到'z'的所有字符,那么这段代码就需要创建26个新string对象。如果字符串较大而且调用频繁,就会出现性能问题。

System.Text.StringBuilder类就是为了解决这类问题。它能够高效工作,但是支持的方法较少。它包含的操作仅限于替换、追加或删除字符串。

可以推测,StringBuilder类对字符串的修改需要在分配给其实例的内存中操作。这样,追加和替换字符就很高效。但是删除和插入依然效率不高。

StringBuilder类有两个重要属性:

  • Length指定字符串的实际长度;
  • Capacity指定分配给字符串的内存的最大长度。

创建StringBuilder类时,可以指定Capacity(容量)的值(一般大于字符串的长度,默认值是16)。在处理时如果容量不够, StringBuilder会将容量翻倍。这个特点和C++中的容器很像。

同样写上面的程序:

StringBuilder greetingBuilder = new StringBuilder("First message, ", );
greetingBuilder.Append("Second message"); for (int i = 'z'; i >= 'a'; i--)
{
char old1 = (char)i;
char new1 = (char)(i+);
greetingBuilder = greetingBuilder.Replace(old1, new1);
}

注意StringBuilder的创建方法和追加字符串的方法都和string不同。注意构造函数的第二个参数容量设为了30。

这段代码只创建了一个StringBuilder对象。并且所有的操作都是在这个对象的内存块中进行的,所以效率很高。

——昨天碰到了一个极端的例子:把string类用StringBuilder类替换后,速度快了60多倍!这个程序是处理一个很长的字符串,对这个字符串的每个字符做循环,循环内执行string的追加操作。这就是StringBuilder类的典型应用场景。从前文可以知道,用string会非常慢。这个时候就一定要用StringBuilder类。

但注意:StringBuilder类不能总是提高性能。其应在处理多个字符串时使用。如果只是连接两个字符串等简单操作,使用String类较好。

另:不能把StringBuilder强制转换为String,只能用ToString()方法。

C#中的字符串——用Stringbuilder类很重要的更多相关文章

  1. 重温java中的String,StringBuffer,StringBuilder类

    不论什么一个系统在开发的过程中, 相信都不会缺少对字符串的处理. 在 java 语言中, 用来处理字符串的的类经常使用的有 3 个: String.StringBuffer.StringBuilder ...

  2. 理解Java中的字符串类型

    1.Java内置对字符串的支持: 所谓的内置支持,即不用像C语言通过char指针实现字符串类型,并且Java的字符串编码是符合Unicode编码标准,这也意味着不用像C++那样通过使用string和w ...

  3. shell中截取字符串的方法总结

    shell中截取字符串的方法有很多种, ${expression}一共有9种使用方法. ${parameter:-word} ${parameter:=word} ${parameter:?word} ...

  4. String/StringBuilder 类 统计字符串中字符出现的次数

    1.1. 训练描述:[方法.String类] 一.需求说明:定义如下字符串: String str = “javajfiewjavajfiowfjavagkljjava”; 二.请分别定义方法统计出: ...

  5. 数据结构和算法 – 4.字符串、 String 类和 StringBuilder 类

    4.1.String类的应用 class String类应用 { static void Main(string[] args) { string astring = "Now is The ...

  6. 从源代码的角度聊聊java中StringBuffer、StringBuilder、String中的字符串拼接

    长久以来,我们被教导字符串的连接最好用StringBuffer.StringBuilder,但是我们却不知道这两者之间的区别.跟字符串相关的一些方法中总是有CharSequence.StringBuf ...

  7. java中String类、StringBuilder类和StringBuffer类详解

    本位转载自http://www.cnblogs.com/dolphin0520/p/3778589.html  版权声明如下: 作者:海子 出处:http://www.cnblogs.com/dolp ...

  8. Android中五大字符串总结(String、StringBuffer、StringBuilder、Spanna

    https://www.aliyun.com/jiaocheng/2861.html?spm=5176.100033.1.35.2ed56b03CbsYFK 摘要:String.StringBuffe ...

  9. 总结 String、StringBuffer与StringBuilder类中常用的方法

    一.String类的常用方法 1.获取: 1)获取字符串str长度 int i = str.length(); 2)根据位置(index)获取字符 char c = str.charAt(index) ...

随机推荐

  1. JS-OO-数据属性,访问器属性

    一.数据属性 Configurable:表示能否通过Delete删除属性从而重新定义属性,能否修改属性的特性,能否把属性修改为访问器属性.默认true. Enumerable:表示能否通过for-in ...

  2. php实现从尾到头打印列表

    php实现从尾到头打印列表 一.总结 4.数组倒序:array_reverse() 5.函数肯定要return,而不是echo 二.php实现从尾到头打印列表 输入一个链表,从尾到头打印链表每个节点的 ...

  3. python链表的实现,有注释

    class Node():                   #node实现,每个node分为两部分:一部分含有链表元素,成数据域;另一部分为指针,指向下一个  __slots__=['_item' ...

  4. 安卓 WebView加载本地图片时居中显示

    在一个项目中使用WebView显示gif图片(自定义的View无法放大gif),当图片过小时只在左侧显示,经过研究发现无论设置android:layout_gravity="center_h ...

  5. 数据类型总结——Array(数组类型)

    相关文章 简书原文:https://www.jianshu.com/p/1e4425383a65 数据类型总结——概述:https://www.cnblogs.com/shcrk/p/9266015. ...

  6. 【44.10%】【codeforces 723B】Text Document Analysis

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  7. Java提高:采用异常链传递异常

    一.分析 异常需要封装,但是仅仅封装还是不够的,还需要传递异常.一个系统的友好型的标识,友好的界面功能是一方面,另一方面就是系统出现非预期的情况的处理方式了. 二.场景 比如我们的JEE项目一般都又三 ...

  8. stl变易算法(一)

    C++ STL的变易算法是一组可以改动容器元素数据的模板函数,可进行序列容器的复制.交换.替换.填充.移除.旋转等.这些算法对迭代器有较高的要求.详细的迭代器类型随各个算法而定,或向前迭代器.或双向迭 ...

  9. NYOJ 364 田忌赛马

    田忌赛马 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描写叙述 Here is a famous story in Chinese history. "That ...

  10. iOS中拉伸图片的几种方式

    假如下面的一张图片,是用来做按钮的背景图片的,原始尺寸是(128 * 112) 按钮背景图片.png 我们通过代码将这张图片设置为按钮的背景图片,假如我们将创建好的按钮的宽高设置为:(W=200, H ...