C# 高效率创建字符串类(StringBuilder)

1、为什么需要StringBuilder类?

因为String类型代表不可变字符串,所以无法对当前String类型实例进行处理.所以FCL提供了System.Text.StringBuilder类型,它可以接受字符串和字符作为参数,并对其进行高效动态处理,最终返回String对象.so,你可以将StringBuilder想象成对String字符串进行各种骚操作的特殊的构造器.

2、StringBuilder处理字符数组和字符串须知

(1)、StringBuilder对象实例包含一个字段,该字符引用了由Char字符构成的数组,可以用StringBuilder的各个成员来操作该字符串数组.

(2)、高效率地缩短字符串或更改字符串中的字符.

(3)、如果字符串变大,超过了事先分配的字符数组大小.StringBuilder会自动分配一个新的、更大的数组,复制字符.并开始使用新数组.前一个数组被垃圾回收.

(4)、当使用StringBuilder处理完目标字符串之后,可以调用StringBuilder的ToString方法即可将StringBuilder的处理完的数组转换成String.这样就会在堆上新建String对象.之后可以继续处理StringBuidler中的字符串.以后可再次调用ToString把它转换成另一个字符串。

常规的对字符串进行多次处理:

            string str = " Hello World";
            //对string进行Trim()一去字符操作
            //执行过程如下:
            //1、先从字符串的开头开始处理,第一个是空格,检索传入的参数中是否有空格,有的话清除(如果第一个是连续的空字符,那么所有的空格都清除)
            //如果第一个被清除掉了,那么继续下一个字母H,和上面一样的流程.如果没有被清除掉,那么不在处理开头,转去清楚末尾的字母
            //2、当开头的字母处理完毕,接着开始处理末尾的,流程和开头的一致
            var res = str.Trim(' ', 'H','o');
            //输出:$ello World$
            Console.WriteLine('$'+res+'$');
            //可以对上一步的处理结果进行处理,但是每次处理的都不是同一个实例
            var res1 = res.Replace('o', 'a');
            Console.WriteLine(res1);
            //可以对上一步的处理结果进行处理,但是每次处理的都不是同一个实例
            var res2 = res1.PadLeft(15, '-');
            Console.WriteLine(res2);

虽然支持,但是每次处理的都不是同一个字符串对象实例,使用StringBuilder就能解决这个问题,保证进行多次字符串操作的同时,还能确保操作的是同一个实例.

            //设置当前StringBuilder的初始大小为1,最大长度为2.
            //如果设置了最大值,那么超过最大值会抛异常,如果没有设置最大值
            //超过初始值,长度会自动扩大两倍
            StringBuilder sb = new StringBuilder(15,20);
            sb.Append(" Hello World");
            sb.Replace('o', 'a');
            Console.WriteLine(sb.ToString());
            //输出完上面的处理结果之后,你可以继续对原有的StringBuilder对象进行操作.
            sb.AppendFormat("{0}",1);
            Console.WriteLine(sb.ToString());
            //注:所有的操作,操作的都是同一个对象,可能扩展过后的StringBuilder对象实例,会是新的对象实例

 3、StringBuilder的基本知识点

(1)、StringBuilder不是基元类型,是引用类型,所以需要使用new来创建对象实例

(2)、StringBuilder类提供了6个构造器,里面的关键参数有以下几个

    capacity一设置StringBuilder初始大小默认长度为16.

    maxCapacity一设置StringBuider的最大容量,默认值为2147483647

    value一字符串(字符串数组)

介绍一个不常用,但是有用的构造函数.

public StringBuilder(string value, int startIndex, int length, int capacity);

给定一个字符串数组,然后通过startIndex和length截取其中的一段字符串作为字符数组,实例化一个StringBuilder对象.

下面是StringBuilder常用的一些不好记的操作:

//设置当前StringBuilder的初始大小为1,最大长度为2.
            //如果设置了最大值,那么超过最大值会抛异常,如果没有设置最大值
            //超过初始值,长度会自动扩大两倍
            StringBuilder sb = new StringBuilder();
            //输出:0 这个长度是当前sb实例中字符串的长度,是字符串的实际长度
            Console.WriteLine(sb.Length);
            //输出:16,默认长度为16,这个长度是当前sb的总长度
            Console.WriteLine(sb.Capacity);
            //输出StringBuilder的最大值.默认最大值为21亿
            Console.WriteLine(sb.MaxCapacity);
            //通过数组的方式给sb中的字符串实例设置值,但是此时没有初始化值,所以程序报错
            //sb[0] = 'A';
            sb.Append("Hello World");
            //输出:H
            Console.WriteLine(sb[0]);
            //修改sb实例的索引为0处的值为A
            sb[0] = 'A';
            //输出:Aello World
            Console.WriteLine(sb.ToString());
            //确保sb的长度为66,如果没有,自动扩大到66
            sb.EnsureCapacity(66);
            //输出:66
            Console.WriteLine(sb.Capacity);

            StringBuilder sb1 = new StringBuilder("abc");
            StringBuilder sb2 = new StringBuilder("abc");
            //输出:True  因为两个StringBuilder实例中的字符串值相等,Capacity也相等
            Console.WriteLine("sb1 equals sb2 is {0}", sb1.Equals(sb2));
            //改变Capacity
            sb1.EnsureCapacity(66);
            //输出:False 因为Capacity不同
            Console.WriteLine("sb1 equals sb2 is {0}", sb1.Equals(sb2));
            StringBuilder sb3 = new StringBuilder("Hello World");
            //注:目标字符串不能有值,它不能像string的copyTo方法一样去覆盖原有的值,复制过去的字符串长度也不能超过目标字符串数组的长度
            var destination = new char[6];
            sb3.CopyTo(0, destination, 0, 2);
            //输出:He
            Console.WriteLine(destination);
            //注:所有的操作,操作的都是同一个对象,可能扩展过后的StringBuilder对象实例,会是新的对象实例
            Console.ReadKey();

4、StringBuilder支持链式操作

因为StringBuidler的大多数方法返回一个StringBuilder引用,所以支持链式操作,代码如下:

            //设置当前StringBuilder的初始大小为1,最大长度为2.
            //如果设置了最大值,那么超过最大值会抛异常,如果没有设置最大值
            //超过初始值,长度会自动扩大两倍
            StringBuilder sb = new StringBuilder("Hell  World");
            sb.Insert(4, 'o').Replace('o', 'a').Remove(5, sb.Length - 5);
            Console.WriteLine("$"+ sb.ToString()+"$");

5、String类和StringBuilder类的差异

String类提供的方法多于StringBuilder类提供的方法,但是StringBuilder提供了更全面的Replace方法.所以StringBuilder无法向String类使用的那样灵活.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Lambda

Java8新特性

1. Lambda 表达式 2. 函数式接口 3. 方法引用与构造器引用 4. Stream API 5. 中的默认方法与静态方法 6....

23060
来自专栏郭耀华‘s Blog

快速排序法

/** * 快速排序实现 * Created by John Kwok on 2018/2/2. */ import java.util.Arrays; ...

33860
来自专栏老马说编程

(91) Lambda表达式 / 计算机程序的思维逻辑

在之前的章节中,我们的讨论基本都是基于Java 7的,从本节开始,我们探讨Java 8的一些特性,主要内容包括: 传递行为代码 - Lambda表达式 函数式...

20880
来自专栏林德熙的博客

C# 循环的判断会进来几次

最近有小伙伴告诉我,在循环的判断条件只会计算一次,本金鱼不相信,于是就做了测试,本文记录我做的测试。

13030
来自专栏Java技术栈

JDK8新特性之Lambda表达式

什么是Lambda表达式 Java 8的一个大亮点是引入Lambda表达式,使用它设计的代码会更加简洁。当开发者在编写Lambda表达式时,也会随之被编译成一个...

35150
来自专栏me的随笔

.NET中可空值类型实现原理

为了让.Net中的值类型可以赋值为null,微软特地添加了Nullable<T>类型,也可简写为T?。但是Nullable<T>自身是结构体,也是值类型,那么它...

10020
来自专栏编程坑太多

Java 8 新特性 Lambda 表达式简单使用

18390
来自专栏Jackson0714

不惧面试:委托

357130
来自专栏DOTNET

C#要点

内容摘要 1 数据类型   1.1表达范围问题   1.2 数组的长度问题   1.3 值类型与引用类型   1.4 匿名类型与隐式类型   1.5硬编码造成的...

29050
来自专栏个人随笔

Java 高级开发必修知识---内部类

Java 内部类分为:   1)成员内部类   2)静态嵌套类   3)方法内部类   4)匿名内部类 ? 内部类的共性 1、内部类仍然是一个独立的类,在编译之...

34590

扫码关注云+社区

领取腾讯云代金券