26.StringBuilder

26.面向对象关联知识点-StringBuilder


26.1 知识点

知识回顾

  • string 是特殊的引用。
  • 每次重新赋值或者拼接时会分配新的内存空间。
  • 如果一个字符串经常改变会非常浪费空间。

StringBuilder的基本概念

  • StringBuilder 是 C# 提供的一个用于处理字符串的公共类。
  • 主要解决的问题是:修改字符串而不创建新的对象。
  • 需要频繁修改和拼接的字符串可以使用它,会产生较少的垃圾,可以提升性能。
  • 使用前需要引用命名空间 using System.Text;

StringBuilder的初始化 直接指明内容

  • 主函数内
// StringBuilder不能直接赋值字符串,要new出来传字符串进去
StringBuilder stringBuilder1 = new StringBuilder("123123123");
Console.WriteLine(stringBuilder1);  // 123123123

StringBuilder的容量

  • 主函数内
// StringBuilder 本质上还是一个字符数组,只不过用了不同的封装,所以还是有容量的概念
// StringBuilder存在一个容量的问题,每次往里面增加时会自动扩容
// 可以类比我们之前自己做的扩容练习题,声明 stringBuilder1 默认就有一定长度(比如8),
// 较小的扩容时不用搬家,提升性能

// 获得 StringBuilder 的字符长度 
Console.WriteLine(stringBuilder1.Length);  // 9,"123123123"长度是9

// 获得 StringBuilder 的容量
Console.WriteLine(stringBuilder1.Capacity);  // 16
// 当字符长度仍小于等于16的时候,不会扩容搬家
// 当字符长度仍大于16的时候,扩容搬家,容量会扩大两倍变成32

// new 出 StringBuilder 有个构造重载,传入容量大小,可以构造时就分配一个对应容量的房间,
// 没超过这个容量就不会扩容搬家
StringBuilder stringBuilder2 = new StringBuilder("我直接分配了100个房间", 100);

StringBuilder的增删查改替换

  • 主函数内

Append 方法,AppendFormat 方法
stringBuilder1.Append("4444");  // 直接尾部拼接上
Console.WriteLine(stringBuilder1);  // 1231231234444
Console.WriteLine(stringBuilder1.Length);  // 13
Console.WriteLine(stringBuilder1.Capacity);  // 16,没超过容量,未扩容

stringBuilder1.AppendFormat("{0}{1}", 100, 999);  // 逐个在尾部拼接上
Console.WriteLine(stringBuilder1);  // 1231231234444100999
Console.WriteLine(stringBuilder1.Length);  // 19
Console.WriteLine(stringBuilder1.Capacity);  // 32,超过容量,扩容两倍

插入

Insert 方法
stringBuilder1.Insert(1, "林文韬");  // 在索引0后1的位置插入字符串
Console.WriteLine(stringBuilder1);  // 1林文韬231231234444100999 

Remove 方法
stringBuilder1.Remove(0, 10);  // 移除掉索引0开始后10位
Console.WriteLine(stringBuilder1);  // 234444100999

直接使用索引器 stringBuilder1[x] get
Console.WriteLine(stringBuilder1[1]);  // 3

直接使用索引器 stringBuilder1[x] set
// string 的索引器是只能 get 不能 set,StringBuilder 又能 get 又能 set
stringBuilder1[0] = 'A';
Console.WriteLine(stringBuilder1);  // A34444100999

替换

Replace 方法
// string 要重新赋值,本体不会改,StringBuilder 会直接改 
stringBuilder1.Replace("1", "林");  // 搜索字符串中的字符1变成字符林
Console.WriteLine(stringBuilder1);  // A34444林00999

清空

Clear 方法
stringBuilder1.Clear();  // 清空字符串,变成空字符
Console.WriteLine(stringBuilder1);  // 输出空

重新赋值

Clear 方法 + Append 方法
stringBuilder1.Clear();
stringBuilder1.Append("林文韬真的帅");
Console.WriteLine(stringBuilder1);  // 林文韬真的帅

判断 StringBuilder 是否和某一个字符串相等

Equals 方法
// StringBuilder 重写了 Equals 方法
if (stringBuilder1.Equals("林文韬真的帅"))
{
    Console.WriteLine("相等");  // 相等
}

26.2 知识点代码

using System;
using System.Text;

namespace Lesson24_面向对象相关_StringBuilder
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("StringBuilder");

            #region 知识回顾
            //string是特殊的引用
            //每次重新赋值或者拼接时会分配新的内存空间
            //如果一个字符串经常改变会非常浪费空间
            #endregion

            #region 知识点一 StringBuilder的基本概念

            //C#提供的一个用于处理字符串的公共类 
            //主要解决的问题是:修改字符串而不创建新的对象
            //需要频繁修改和拼接的字符串可以使用它,会产生较少的垃圾,可以提升性能
            //使用前 需要引用命名空间 using System.Text;

            #endregion

            //主函数内

            #region 知识点二 StringBuilder的初始化 直接指明内容

            //StringBuilder不能直接赋值字符串 要new出来传字符串进去
            StringBuilder stringBuilder1 = new StringBuilder("123123123");
            Console.WriteLine(stringBuilder1);//123123123

            #endregion

            #region 知识点三 StringBuilder的容量

            //StringBuilder本质上还是一个字符数组 只不过用了不同的封装 所以还是有容量的概念
            //StringBuilder存在一个容量的问题,每次往里面增加时 会自动扩容
            //可以类比我们之前自己做的扩容练习题 声明stringBuilder1默认就有一定长度(比如8) 较小的扩容时不用搬家 提升性能

            //获得StringBuilder的字符长度 
            Console.WriteLine(stringBuilder1.Length);//9 123123123长度是9

            //获得StringBuilder的容量
            Console.WriteLine(stringBuilder1.Capacity);//16
            //当字符长度仍小于等于16的时候 不会扩容搬家
            //当字符长度仍大于16的时候 扩容搬家 容量会扩大两倍变成32

            //new出StringBuilder有个构造重载 传入容量大小可以构造时就分配一个对应容量的房间房间 没超过这个容量就不会扩容搬家
            StringBuilder stringBuilder2 = new StringBuilder("我直接分配了100个房间", 100);

            #endregion

            #region 知识点四 StringBuilder的增删查改替换

            //增 Append方法 AppendFormat方法
            stringBuilder1.Append("4444");//直接尾部拼接上
            Console.WriteLine(stringBuilder1);//1231231234444
            Console.WriteLine(stringBuilder1.Length);//13
            Console.WriteLine(stringBuilder1.Capacity);//16 没超过容量 未扩容
            stringBuilder1.AppendFormat("{0}{1}", 100, 999);//逐个在尾部拼接上
            Console.WriteLine(stringBuilder1);//1231231234444100999
            Console.WriteLine(stringBuilder1.Length);//19
            Console.WriteLine(stringBuilder1.Capacity);//32 超过容量 扩容两倍

            //插入 Insert方法
            stringBuilder1.Insert(1, "林文韬");//在索引0后1的位置插入字符串
            Console.WriteLine(stringBuilder1);//1林文韬231231234444100999 

            //删 Remove方法
            stringBuilder1.Remove(0, 10);//移除掉索引0开始后10位
            Console.WriteLine(stringBuilder1);//234444100999

            //查 直接使用索引器 stringBuilder1[x] get
            Console.WriteLine(stringBuilder1[1]);//3

            //改 直接使用索引器 stringBuilder1[x] set
            //string的索引器是只能get不能set stringBuilder又能get又能set
            stringBuilder1[0] = 'A';
            Console.WriteLine(stringBuilder1);//A34444100999

            //替换 Replace方法
            //string要重新赋值 本体不会改 stringBuilder会直接改 
            stringBuilder1.Replace("1", "林");//搜索字符串中的字符1变成字符林
            Console.WriteLine(stringBuilder1);//A34444林00999

            //清空 Clear方法
            stringBuilder1.Clear();//清空字符串 变成空字符
            Console.WriteLine(stringBuilder1);//输出空

            //重新赋值 Clear方法 + Append方法
            stringBuilder1.Clear();
            stringBuilder1.Append("林文韬真的帅");
            Console.WriteLine(stringBuilder1);//林文韬真的帅

            //判断StringBuilder是否和某一个字符串相等 Equals方法
            //StringBuilder重写了万物之父的Equals方法
            if (stringBuilder1.Equals("林文韬真的帅"))
            {
                Console.WriteLine("相等");//相等
            }

            #endregion


        }
    }
}

26.3 练习题

请描述 stringStringBuilder 的区别

  • string 相对 StringBuilder 更容易产生垃圾:

    • string 是不可变的,每次对字符串进行修改、拼接、截取等操作都会创建新的字符串对象,导致内存中产生垃圾。
    • StringBuilder 是可变的,它使用一个可扩展的字符缓冲区,允许在现有对象的基础上进行修改而不创建新对象,因此更加节省内存。
  • string 相对 StringBuilder 更加灵活:

    • string 提供了许多字符串操作的方法,如 SubstringToUpperToLower 等,使得对字符串的处理更加方便。
    • StringBuilder 主要用于频繁的字符串拼接和修改,而提供的方法相对简单,功能相对较少。

如何选择 string 还是 StringBuilder?

  • 需要频繁修改拼接的字符串时,可以使用 StringBuilder
  • 需要使用 string 独特的方法来处理一些特殊逻辑时,可以使用 string

如何优化内存

内存优化方面:

  • new 对象,尽量重用:

    • 减少对象的创建,尽量重用已有的对象,避免产生过多的垃圾。
  • 合理使用 static

    • 使用 static 关键字定义静态成员,可以使这些成员在整个应用程序生命周期内只有一个实例,减少对象的创建和销毁。
  • 合理使用 stringStringBuilder

    • 对于频繁修改的字符串,使用 StringBuilder 而不是 string,以减少不必要的内存开销。

减少垃圾回收(GC)方面:

  • 避免频繁大对象的创建和释放:

    • 大对象生命周期结束时,会导致大对象堆内存的回收,频繁的大对象回收可能会影响应用程序性能。
  • 使用对象池:

    • 对象池可以缓存并重用对象,避免频繁地创建和销毁对象,减轻垃圾回收的压力。
  • 小心使用终结器(Finalizer):

    • 终结器可能导致对象的延迟回收,增加垃圾回收的不确定性和开销。尽量避免过度使用终结器。

通过合理的内存管理和垃圾回收策略,可以有效优化应用程序的性能和资源利用。


26.4 练习题代码

using System;

namespace Lesson24_练习题
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("string和StringBuilder");

            #region 练习题一 请描述string和stringbuilder的区别

            //1.string相对stringbuilder 更容易产生垃圾 每次修改拼接都会产生垃圾
            //2.string相对stringbuilder 更加灵活 因为它提供了更多的方法供使用
            //如何选择string还是stringbuilder?
            //需要频繁修改拼接的字符串可以使用stringbuilder
            //需要使用string独特的一些方法来处理一些特殊逻辑时可以使用string

            #endregion

            #region 练习题二 如何优化内存

            //根据现在学过的知识回答 以后可以回答更多内容

            //内存优化 从两个方面去解答 
            //1.如何节约内存
            //2.如何尽量少的GC(垃圾回收)

            //具体优化做法
            //少new对象 少产生垃圾
            //合理使用static 
            //合理使用string和stringbuilder

            #endregion
        }
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏