StringBuilder的实现与技巧

    技术2022-05-11  88

    在上一篇进一步了解String 中,发现了string的不便之处,而string的替代解决方案就是StringBuilder的使用..它的使用也很简单System.Text.StringBuilder sb = new System.Text.StringBuilder();这样就初始化了一个StringBuilder ..之后我们可以通过Append()来追加字符串填充到sb中..在你初始化一个StringBuilder 之后,它会自动申请一个默认的StringBuilder 容量(默认值是16),这个容量是由Capacity来控制的.并且允许,我们根据需要来控制Capacity的大小,也可以通过Length来获取或设置StringBuilder 的长度..先来看Length的用法:

    1System.Text.StringBuilder sb = new System.Text.StringBuilder();2sb.Append( "123456789" );//添加一个字符串3sb.Length = 3;//设置容量为34Console.WriteLine( sb.ToString() );//这里输出:12356sb.Length = 30;//重新设置容量为307Console.WriteLine( sb.ToString() + ",结尾");//这里在原来字符串后面补齐空格,至到Length的为308Console.WriteLine( sb.Length );//这里输出的长度为30

    通过上面的代码,我们可以看出如果StringBuilder 中的字符长度小于Length的值,则StringBuilder 将会用空格硬填充StringBuilder ,以满足符合长度的设置..如果StringBuilder 中的字符长度大于Length的值,则StringBuilder 将会截取从第一位开始的Length个字符..而忽略超出的部分..再来看看最重要的部分Carpacity的用法:

     1System.Text.StringBuilder sb = new System.Text.StringBuilder();//初始化一个StringBuilder 2Console.Write( "Capacity:" + sb.Capacity );//这里的Capacity会自动扩大 3Console.WriteLine( "/t Length:" + sb.Length ); 4 5sb.Append( '1',17 );//添加一个字符串,这里故意添加17个字符,是为了看到Capacity是如何被扩充的 6Console.Write( "Capacity:" + sb.Capacity );//这里的Capacity会自动扩大 7Console.WriteLine( "/t Length:" + sb.Length ); 8 9sb.Append( '2',32 );//添加一个字符串10Console.Write( "Capacity:" + sb.Capacity );//这里的Capacity会自动扩大11Console.WriteLine( "/t Length:" + sb.Length );1213sb.Append( '3',64 );//添加一个字符串14Console.Write( "Capacity:" + sb.Capacity );//这里的Capacity会自动扩大15Console.WriteLine( "/t Length:" + sb.Length );1617//注意这里:如果你取消Remove这步操作,将会引发ArgumentOutOfRangeException异常,因为当前容量小于1819//Length,这在自己控制StringBuilder的时候务必要注意容量溢出的问题2021sb.Remove(0,sb.Length);//移出全部内容,再测试22sb.Capacity = 1;//重新定义了容量23sb.Append( 'a',2 );24Console.Write( "Capacity:" + sb.Capacity );//这里的Capacity会自动扩大25Console.WriteLine( "/t Length:" + sb.Length );2627sb.Append( 'b',4 );28Console.Write( "Capacity:" + sb.Capacity );//这里的Capacity会自动扩大29Console.WriteLine( "/t Length:" + sb.Length );3031sb.Append( 'c',6 );32Console.Write( "Capacity:" + sb.Capacity );//这里的Capacity会自动扩大33Console.WriteLine( "/t Length:" + sb.Length 上面的代码输出的结果: 1 Capacity: 16      Length: 0      // 输出第一次,默认的Capacity是16 2 Capacity: 32      Length: 17      // 第二次,我们故意添加了17个字符,于是Capacity=Capacity*2 3 Capacity: 64      Length: 49      // 继续超出,则Capacity=Capacity*2 4 Capacity: 128      Length: 113 5 Capacity: 3      Length: 2      // 清空内容后,设置Capacity=1,重新添加了字符 6 Capacity: 7       Length: 6      // 后面的结果都类似 7 Capacity: 14      Length: 12 从上面的代码和结果可以说明StringBuilder中容量Capacity是如何增加的:创建一个StringBuilder之后,默认的Capacity初始化为16,接着我们添加17个字符,以方便看到Capacity的扩充后的值..大家在修改Capacity的时候,一定要注意21行的注释,一定要确保Capacity >= Length,否则会引发ArgumentOutOfRangeException异常...看完结果,就可以推断出Capacity的公式:if ( Capacity < Length && Capacity > 0 ){      Capacity *= 2;}

     1System.Text.StringBuilder sb = new System.Text.StringBuilder();//初始化一个StringBuilder 2Console.Write( "Capacity:" + sb.Capacity );//这里的Capacity会自动扩大 3Console.WriteLine( "/t Length:" + sb.Length ); 4 5sb.Append( '1',17 );//添加一个字符串,这里故意添加17个字符,是为了看到Capacity是如何被扩充的 6Console.Write( "Capacity:" + sb.Capacity );//这里的Capacity会自动扩大 7Console.WriteLine( "/t Length:" + sb.Length ); 8 9sb.Append( '2',32 );//添加一个字符串10Console.Write( "Capacity:" + sb.Capacity );//这里的Capacity会自动扩大11Console.WriteLine( "/t Length:" + sb.Length );1213sb.Append( '3',64 );//添加一个字符串14Console.Write( "Capacity:" + sb.Capacity );//这里的Capacity会自动扩大15Console.WriteLine( "/t Length:" + sb.Length );1617//注意这里:如果你取消Remove这步操作,将会引发ArgumentOutOfRangeException异常,因为当前容量小于1819//Length,这在自己控制StringBuilder的时候务必要注意容量溢出的问题2021sb.Remove(0,sb.Length);//移出全部内容,再测试22sb.Capacity = 1;//重新定义了容量23sb.Append( 'a',2 );24Console.Write( "Capacity:" + sb.Capacity );//这里的Capacity会自动扩大25Console.WriteLine( "/t Length:" + sb.Length );2627sb.Append( 'b',4 );28Console.Write( "Capacity:" + sb.Capacity );//这里的Capacity会自动扩大29Console.WriteLine( "/t Length:" + sb.Length );3031sb.Append( 'c',6 );32Console.Write( "Capacity:" + sb.Capacity );//这里的Capacity会自动扩大33Console.WriteLine( "/t Length:" + sb.Length 上面的代码输出的结果: 1 Capacity: 16      Length: 0      // 输出第一次,默认的Capacity是16 2 Capacity: 32      Length: 17      // 第二次,我们故意添加了17个字符,于是Capacity=Capacity*2 3 Capacity: 64      Length: 49      // 继续超出,则Capacity=Capacity*2 4 Capacity: 128      Length: 113 5 Capacity: 3      Length: 2      // 清空内容后,设置Capacity=1,重新添加了字符 6 Capacity: 7       Length: 6      // 后面的结果都类似 7 Capacity: 14      Length: 12 从上面的代码和结果可以说明StringBuilder中容量Capacity是如何增加的:创建一个StringBuilder之后,默认的Capacity初始化为16,接着我们添加17个字符,以方便看到Capacity的扩充后的值..大家在修改Capacity的时候,一定要注意21行的注释,一定要确保Capacity >= Length,否则会引发ArgumentOutOfRangeException异常...看完结果,就可以推断出Capacity的公式:if ( Capacity < Length && Capacity > 0 ){      Capacity *= 2;}

    通过上面的代码,我们可以看出如果StringBuilder 中的字符长度小于Length的值,则StringBuilder 将会用空格硬填充StringBuilder ,以满足符合长度的设置..如果StringBuilder 中的字符长度大于Length的值,则StringBuilder 将会截取从第一位开始的Length个字符..而忽略超出的部分..再来看看最重要的部分Carpacity的用法:  1 System.Text.StringBuilder sb  =   new  System.Text.StringBuilder(); // 初始化一个StringBuilder  2 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大  3 Console.WriteLine(  " /t Length: "   +  sb.Length );  4  5 sb.Append(  ' 1 ' , 17  ); // 添加一个字符串,这里故意添加17个字符,是为了看到Capacity是如何被扩充的  6 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大  7 Console.WriteLine(  " /t Length: "   +  sb.Length );  8  9 sb.Append(  ' 2 ' , 32  ); // 添加一个字符串 10 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 11 Console.WriteLine(  " /t Length: "   +  sb.Length ); 12 13 sb.Append(  ' 3 ' , 64  ); // 添加一个字符串 14 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 15 Console.WriteLine(  " /t Length: "   +  sb.Length ); 16 17 // 注意这里:如果你取消Remove这步操作,将会引发ArgumentOutOfRangeException异常,因为当前容量小于 18 19 //Length,这在自己控制StringBuilder的时候务必要注意容量溢出的问题 20 21 sb.Remove( 0 ,sb.Length); // 移出全部内容,再测试 22 sb.Capacity  =   1 ; // 重新定义了容量 23 sb.Append(  ' a ' , 2  ); 24 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 25 Console.WriteLine(  " /t Length: "   +  sb.Length ); 26 27 sb.Append(  ' b ' , 4  ); 28 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 29 Console.WriteLine(  " /t Length: "   +  sb.Length ); 30 31 sb.Append(  ' c ' , 6  ); 32 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 33 Console.WriteLine(  " /t Length: "   +  sb.Length 上面的代码输出的结果: 1 Capacity: 16      Length: 0      // 输出第一次,默认的Capacity是16 2 Capacity: 32      Length: 17      // 第二次,我们故意添加了17个字符,于是Capacity=Capacity*2 3 Capacity: 64      Length: 49      // 继续超出,则Capacity=Capacity*2 4 Capacity: 128      Length: 113 5 Capacity: 3      Length: 2      // 清空内容后,设置Capacity=1,重新添加了字符 6 Capacity: 7       Length: 6      // 后面的结果都类似 7 Capacity: 14      Length: 12 从上面的代码和结果可以说明StringBuilder中容量Capacity是如何增加的:创建一个StringBuilder之后,默认的Capacity初始化为16,接着我们添加17个字符,以方便看到Capacity的扩充后的值..大家在修改Capacity的时候,一定要注意21行的注释,一定要确保Capacity >= Length,否则会引发ArgumentOutOfRangeException异常...看完结果,就可以推断出Capacity的公式:if ( Capacity < Length && Capacity > 0 ){      Capacity *= 2;}

    1 System.Text.StringBuilder sb  =   new  System.Text.StringBuilder(); 2 sb.Append(  " 123456789 "  ); // 添加一个字符串 3 sb.Length  =   3 ; // 设置容量为3 4 Console.WriteLine( sb.ToString() ); // 这里输出:123 5 6 sb.Length  =   30 ; // 重新设置容量为30 7 Console.WriteLine( sb.ToString()  +   " ,结尾 " ); // 这里在原来字符串后面补齐空格,至到Length的为30 8 Console.WriteLine( sb.Length ); // 这里输出的长度为30

    通过上面的代码,我们可以看出如果StringBuilder 中的字符长度小于Length的值,则StringBuilder 将会用空格硬填充StringBuilder ,以满足符合长度的设置..如果StringBuilder 中的字符长度大于Length的值,则StringBuilder 将会截取从第一位开始的Length个字符..而忽略超出的部分..再来看看最重要的部分Carpacity的用法:

     1 System.Text.StringBuilder sb  =   new  System.Text.StringBuilder(); // 初始化一个StringBuilder  2 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大  3 Console.WriteLine(  " /t Length: "   +  sb.Length );  4  5 sb.Append(  ' 1 ' , 17  ); // 添加一个字符串,这里故意添加17个字符,是为了看到Capacity是如何被扩充的  6 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大  7 Console.WriteLine(  " /t Length: "   +  sb.Length );  8  9 sb.Append(  ' 2 ' , 32  ); // 添加一个字符串 10 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 11 Console.WriteLine(  " /t Length: "   +  sb.Length ); 12 13 sb.Append(  ' 3 ' , 64  ); // 添加一个字符串 14 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 15 Console.WriteLine(  " /t Length: "   +  sb.Length ); 16 17 // 注意这里:如果你取消Remove这步操作,将会引发ArgumentOutOfRangeException异常,因为当前容量小于 18 19 //Length,这在自己控制StringBuilder的时候务必要注意容量溢出的问题 20 21 sb.Remove( 0 ,sb.Length); // 移出全部内容,再测试 22 sb.Capacity  =   1 ; // 重新定义了容量 23 sb.Append(  ' a ' , 2  ); 24 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 25 Console.WriteLine(  " /t Length: "   +  sb.Length ); 26 27 sb.Append(  ' b ' , 4  ); 28 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 29 Console.WriteLine(  " /t Length: "   +  sb.Length ); 30 31 sb.Append(  ' c ' , 6  ); 32 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 33 Console.WriteLine(  " /t Length: "   +  sb.Length 上面的代码输出的结果: 1 Capacity: 16      Length: 0      // 输出第一次,默认的Capacity是16 2 Capacity: 32      Length: 17      // 第二次,我们故意添加了17个字符,于是Capacity=Capacity*2 3 Capacity: 64      Length: 49      // 继续超出,则Capacity=Capacity*2 4 Capacity: 128      Length: 113 5 Capacity: 3      Length: 2      // 清空内容后,设置Capacity=1,重新添加了字符 6 Capacity: 7       Length: 6      // 后面的结果都类似 7 Capacity: 14      Length: 12 从上面的代码和结果可以说明StringBuilder中容量Capacity是如何增加的:创建一个StringBuilder之后,默认的Capacity初始化为16,接着我们添加17个字符,以方便看到Capacity的扩充后的值..大家在修改Capacity的时候,一定要注意21行的注释,一定要确保Capacity >= Length,否则会引发ArgumentOutOfRangeException异常...看完结果,就可以推断出Capacity的公式: if ( Capacity < Length && Capacity > 0 ){       Capacity *= 2; }

     1 System.Text.StringBuilder sb  =   new  System.Text.StringBuilder(); // 初始化一个StringBuilder  2 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大  3 Console.WriteLine(  " /t Length: "   +  sb.Length );  4  5 sb.Append(  ' 1 ' , 17  ); // 添加一个字符串,这里故意添加17个字符,是为了看到Capacity是如何被扩充的  6 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大  7 Console.WriteLine(  " /t Length: "   +  sb.Length );  8  9 sb.Append(  ' 2 ' , 32  ); // 添加一个字符串 10 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 11 Console.WriteLine(  " /t Length: "   +  sb.Length ); 12 13 sb.Append(  ' 3 ' , 64  ); // 添加一个字符串 14 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 15 Console.WriteLine(  " /t Length: "   +  sb.Length ); 16 17 // 注意这里:如果你取消Remove这步操作,将会引发ArgumentOutOfRangeException异常,因为当前容量小于 18 19 //Length,这在自己控制StringBuilder的时候务必要注意容量溢出的问题 20 21 sb.Remove( 0 ,sb.Length); // 移出全部内容,再测试 22 sb.Capacity  =   1 ; // 重新定义了容量 23 sb.Append(  ' a ' , 2  ); 24 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 25 Console.WriteLine(  " /t Length: "   +  sb.Length ); 26 27 sb.Append(  ' b ' , 4  ); 28 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 29 Console.WriteLine(  " /t Length: "   +  sb.Length ); 30 31 sb.Append(  ' c ' , 6  ); 32 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 33 Console.WriteLine(  " /t Length: "   +  sb.Length 上面的代码输出的结果: 1 Capacity: 16      Length: 0      // 输出第一次,默认的Capacity是16 2 Capacity: 32      Length: 17      // 第二次,我们故意添加了17个字符,于是Capacity=Capacity*2 3 Capacity: 64      Length: 49      // 继续超出,则Capacity=Capacity*2 4 Capacity: 128      Length: 113 5 Capacity: 3      Length: 2      // 清空内容后,设置Capacity=1,重新添加了字符 6 Capacity: 7       Length: 6      // 后面的结果都类似 7 Capacity: 14      Length: 12 从上面的代码和结果可以说明StringBuilder中容量Capacity是如何增加的:创建一个StringBuilder之后,默认的Capacity初始化为16,接着我们添加17个字符,以方便看到Capacity的扩充后的值..大家在修改Capacity的时候,一定要注意21行的注释,一定要确保Capacity >= Length,否则会引发ArgumentOutOfRangeException异常...看完结果,就可以推断出Capacity的公式: if ( Capacity < Length && Capacity > 0 ){       Capacity *= 2; }

    通过上面的代码,我们可以看出如果StringBuilder 中的字符长度小于Length的值,则StringBuilder 将会用空格硬填充StringBuilder ,以满足符合长度的设置..如果StringBuilder 中的字符长度大于Length的值,则StringBuilder 将会截取从第一位开始的Length个字符..而忽略超出的部分..再来看看最重要的部分Carpacity的用法:  1 System.Text.StringBuilder sb  =   new  System.Text.StringBuilder(); // 初始化一个StringBuilder  2 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大  3 Console.WriteLine(  " /t Length: "   +  sb.Length );  4  5 sb.Append(  ' 1 ' , 17  ); // 添加一个字符串,这里故意添加17个字符,是为了看到Capacity是如何被扩充的  6 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大  7 Console.WriteLine(  " /t Length: "   +  sb.Length );  8  9 sb.Append(  ' 2 ' , 32  ); // 添加一个字符串 10 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 11 Console.WriteLine(  " /t Length: "   +  sb.Length ); 12 13 sb.Append(  ' 3 ' , 64  ); // 添加一个字符串 14 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 15 Console.WriteLine(  " /t Length: "   +  sb.Length ); 16 17 // 注意这里:如果你取消Remove这步操作,将会引发ArgumentOutOfRangeException异常,因为当前容量小于 18 19 //Length,这在自己控制StringBuilder的时候务必要注意容量溢出的问题 20 21 sb.Remove( 0 ,sb.Length); // 移出全部内容,再测试 22 sb.Capacity  =   1 ; // 重新定义了容量 23 sb.Append(  ' a ' , 2  ); 24 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 25 Console.WriteLine(  " /t Length: "   +  sb.Length ); 26 27 sb.Append(  ' b ' , 4  ); 28 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 29 Console.WriteLine(  " /t Length: "   +  sb.Length ); 30 31 sb.Append(  ' c ' , 6  ); 32 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 33 Console.WriteLine(  " /t Length: "   +  sb.Length 上面的代码输出的结果: 1 Capacity: 16      Length: 0      // 输出第一次,默认的Capacity是16 2 Capacity: 32      Length: 17      // 第二次,我们故意添加了17个字符,于是Capacity=Capacity*2 3 Capacity: 64      Length: 49      // 继续超出,则Capacity=Capacity*2 4 Capacity: 128      Length: 113 5 Capacity: 3      Length: 2      // 清空内容后,设置Capacity=1,重新添加了字符 6 Capacity: 7       Length: 6      // 后面的结果都类似 7 Capacity: 14      Length: 12 从上面的代码和结果可以说明StringBuilder中容量Capacity是如何增加的:创建一个StringBuilder之后,默认的Capacity初始化为16,接着我们添加17个字符,以方便看到Capacity的扩充后的值..大家在修改Capacity的时候,一定要注意21行的注释,一定要确保Capacity >= Length,否则会引发ArgumentOutOfRangeException异常...看完结果,就可以推断出Capacity的公式:if ( Capacity < Length && Capacity > 0 ){      Capacity *= 2;}

    1 System.Text.StringBuilder sb  =   new  System.Text.StringBuilder(); 2 sb.Append(  " 123456789 "  ); // 添加一个字符串 3 sb.Length  =   3 ; // 设置容量为3 4 Console.WriteLine( sb.ToString() ); // 这里输出:123 5 6 sb.Length  =   30 ; // 重新设置容量为30 7 Console.WriteLine( sb.ToString()  +   " ,结尾 " ); // 这里在原来字符串后面补齐空格,至到Length的为30 8 Console.WriteLine( sb.Length ); // 这里输出的长度为30

    通过上面的代码,我们可以看出如果StringBuilder 中的字符长度小于Length的值,则StringBuilder 将会用空格硬填充StringBuilder ,以满足符合长度的设置..如果StringBuilder 中的字符长度大于Length的值,则StringBuilder 将会截取从第一位开始的Length个字符..而忽略超出的部分..再来看看最重要的部分Carpacity的用法:

     1 System.Text.StringBuilder sb  =   new  System.Text.StringBuilder(); // 初始化一个StringBuilder  2 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大  3 Console.WriteLine(  " /t Length: "   +  sb.Length );  4  5 sb.Append(  ' 1 ' , 17  ); // 添加一个字符串,这里故意添加17个字符,是为了看到Capacity是如何被扩充的  6 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大  7 Console.WriteLine(  " /t Length: "   +  sb.Length );  8  9 sb.Append(  ' 2 ' , 32  ); // 添加一个字符串 10 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 11 Console.WriteLine(  " /t Length: "   +  sb.Length ); 12 13 sb.Append(  ' 3 ' , 64  ); // 添加一个字符串 14 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 15 Console.WriteLine(  " /t Length: "   +  sb.Length ); 16 17 // 注意这里:如果你取消Remove这步操作,将会引发ArgumentOutOfRangeException异常,因为当前容量小于 18 19 //Length,这在自己控制StringBuilder的时候务必要注意容量溢出的问题 20 21 sb.Remove( 0 ,sb.Length); // 移出全部内容,再测试 22 sb.Capacity  =   1 ; // 重新定义了容量 23 sb.Append(  ' a ' , 2  ); 24 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 25 Console.WriteLine(  " /t Length: "   +  sb.Length ); 26 27 sb.Append(  ' b ' , 4  ); 28 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 29 Console.WriteLine(  " /t Length: "   +  sb.Length ); 30 31 sb.Append(  ' c ' , 6  ); 32 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 33 Console.WriteLine(  " /t Length: "   +  sb.Length 上面的代码输出的结果: 1 Capacity: 16      Length: 0      // 输出第一次,默认的Capacity是16 2 Capacity: 32      Length: 17      // 第二次,我们故意添加了17个字符,于是Capacity=Capacity*2 3 Capacity: 64      Length: 49      // 继续超出,则Capacity=Capacity*2 4 Capacity: 128      Length: 113 5 Capacity: 3      Length: 2      // 清空内容后,设置Capacity=1,重新添加了字符 6 Capacity: 7       Length: 6      // 后面的结果都类似 7 Capacity: 14      Length: 12 从上面的代码和结果可以说明StringBuilder中容量Capacity是如何增加的:创建一个StringBuilder之后,默认的Capacity初始化为16,接着我们添加17个字符,以方便看到Capacity的扩充后的值..大家在修改Capacity的时候,一定要注意21行的注释,一定要确保Capacity >= Length,否则会引发ArgumentOutOfRangeException异常...看完结果,就可以推断出Capacity的公式: if ( Capacity < Length && Capacity > 0 ){       Capacity *= 2; }

     1 System.Text.StringBuilder sb  =   new  System.Text.StringBuilder(); // 初始化一个StringBuilder  2 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大  3 Console.WriteLine(  " /t Length: "   +  sb.Length );  4  5 sb.Append(  ' 1 ' , 17  ); // 添加一个字符串,这里故意添加17个字符,是为了看到Capacity是如何被扩充的  6 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大  7 Console.WriteLine(  " /t Length: "   +  sb.Length );  8  9 sb.Append(  ' 2 ' , 32  ); // 添加一个字符串 10 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 11 Console.WriteLine(  " /t Length: "   +  sb.Length ); 12 13 sb.Append(  ' 3 ' , 64  ); // 添加一个字符串 14 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 15 Console.WriteLine(  " /t Length: "   +  sb.Length ); 16 17 // 注意这里:如果你取消Remove这步操作,将会引发ArgumentOutOfRangeException异常,因为当前容量小于 18 19 //Length,这在自己控制StringBuilder的时候务必要注意容量溢出的问题 20 21 sb.Remove( 0 ,sb.Length); // 移出全部内容,再测试 22 sb.Capacity  =   1 ; // 重新定义了容量 23 sb.Append(  ' a ' , 2  ); 24 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 25 Console.WriteLine(  " /t Length: "   +  sb.Length ); 26 27 sb.Append(  ' b ' , 4  ); 28 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 29 Console.WriteLine(  " /t Length: "   +  sb.Length ); 30 31 sb.Append(  ' c ' , 6  ); 32 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 33 Console.WriteLine(  " /t Length: "   +  sb.Length 上面的代码输出的结果: 1 Capacity: 16      Length: 0      // 输出第一次,默认的Capacity是16 2 Capacity: 32      Length: 17      // 第二次,我们故意添加了17个字符,于是Capacity=Capacity*2 3 Capacity: 64      Length: 49      // 继续超出,则Capacity=Capacity*2 4 Capacity: 128      Length: 113 5 Capacity: 3      Length: 2      // 清空内容后,设置Capacity=1,重新添加了字符 6 Capacity: 7       Length: 6      // 后面的结果都类似 7 Capacity: 14      Length: 12 从上面的代码和结果可以说明StringBuilder中容量Capacity是如何增加的:创建一个StringBuilder之后,默认的Capacity初始化为16,接着我们添加17个字符,以方便看到Capacity的扩充后的值..大家在修改Capacity的时候,一定要注意21行的注释,一定要确保Capacity >= Length,否则会引发ArgumentOutOfRangeException异常...看完结果,就可以推断出Capacity的公式: if ( Capacity < Length && Capacity > 0 ){       Capacity *= 2; }

     1 System.Text.StringBuilder sb  =   new  System.Text.StringBuilder(); // 初始化一个StringBuilder  2 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大  3 Console.WriteLine(  " /t Length: "   +  sb.Length );  4  5 sb.Append(  ' 1 ' , 17  ); // 添加一个字符串,这里故意添加17个字符,是为了看到Capacity是如何被扩充的  6 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大  7 Console.WriteLine(  " /t Length: "   +  sb.Length );  8  9 sb.Append(  ' 2 ' , 32  ); // 添加一个字符串 10 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 11 Console.WriteLine(  " /t Length: "   +  sb.Length ); 12 13 sb.Append(  ' 3 ' , 64  ); // 添加一个字符串 14 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 15 Console.WriteLine(  " /t Length: "   +  sb.Length ); 16 17 // 注意这里:如果你取消Remove这步操作,将会引发ArgumentOutOfRangeException异常,因为当前容量小于 18 19 //Length,这在自己控制StringBuilder的时候务必要注意容量溢出的问题 20 21 sb.Remove( 0 ,sb.Length); // 移出全部内容,再测试 22 sb.Capacity  =   1 ; // 重新定义了容量 23 sb.Append(  ' a ' , 2  ); 24 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 25 Console.WriteLine(  " /t Length: "   +  sb.Length ); 26 27 sb.Append(  ' b ' , 4  ); 28 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 29 Console.WriteLine(  " /t Length: "   +  sb.Length ); 30 31 sb.Append(  ' c ' , 6  ); 32 Console.Write(  " Capacity: "   +  sb.Capacity ); // 这里的Capacity会自动扩大 33 Console.WriteLine(  " /t Length: "   +  sb.Length 上面的代码输出的结果: 1 Capacity: 16      Length: 0      // 输出第一次,默认的Capacity是16 2 Capacity: 32      Length: 17      // 第二次,我们故意添加了17个字符,于是Capacity=Capacity*2 3 Capacity: 64      Length: 49      // 继续超出,则Capacity=Capacity*2 4 Capacity: 128      Length: 113 5 Capacity: 3      Length: 2      // 清空内容后,设置Capacity=1,重新添加了字符 6 Capacity: 7       Length: 6      // 后面的结果都类似 7 Capacity: 14      Length: 12 从上面的代码和结果可以说明StringBuilder中容量Capacity是如何增加的:创建一个StringBuilder之后,默认的Capacity初始化为16,接着我们添加17个字符,以方便看到Capacity的扩充后的值..大家在修改Capacity的时候,一定要注意21行的注释,一定要确保Capacity >= Length,否则会引发ArgumentOutOfRangeException异常...看完结果,就可以推断出Capacity的公式: if ( Capacity < Length && Capacity > 0 ){       Capacity *= 2; } OK..看到公式就明白了..StringBuilder是以当前的Capacity*2来扩充的..所以,在使用StringBuilder需要特别注意,尤其是要拼接或追加N多字符的时候,要注意技巧的使用,可以适当的,有预见性的设置Capacity的值,避免造成过大内存的浪费,节约无谓的内存空间..例如,下列代码就可以根据情况自动的扩展,而避免了较大的内存浪费.  1 System.Text.StringBuilder sb  =   new  System.Text.StringBuilder();  2 int  i  =   0 ;  3 long  StartTime   =  DateTime.Now.Ticks;  4 while  ( i  <   100000  )  { 5sb.Append( i.ToString() ); 6i++; 7}  8 long  EndTime   =  DateTime.Now.Ticks;  9 10 Console.WriteLine(  " 时间: "   +  ( EndTime - StartTime )  +   " /t Capacity: " +  sb.Capacity  +   " /t Length: "   11 12 +  sb.Length); 13 14 System.Text.StringBuilder sb1  =   new  System.Text.StringBuilder(); 15 =   0 ; 16 StartTime   =  DateTime.Now.Ticks; 17 while  ( i  <   100000  )  18 {19if ( sb1.Capacity <= sb1.Length )//先判断是否>Length20sb1.Capacity += 7;//这里一定要根据情况的增加容量,否则会有性能上的消耗21sb1.Append( i.ToString() );22i++;23} 24 EndTime   =  DateTime.Now.Ticks; 25 26 Console.WriteLine(  " 时间: "   +  ( EndTime - StartTime )  +   " /t Capacity: " +  sb1.Capacity  +   " /t  27 28 Length: "  + sb1.Length); 需要特别说明的一点是,自动增加的容量,一定要根据实际预见的情况而改变,否则不但起不到优化的作用,反而会影响到程序的性能..另外,如果有时间的话,可以测试一下下面的代码,用string和StringBuilder拼接字符串的区别..你会吓到的!!  1 System.Text.StringBuilder sb  =   new  System.Text.StringBuilder();  2 int  i  =   0 ;  3 long  StartTime   =  DateTime.Now.Ticks;  4 while  ( i  <   100000  )  { 5sb.Append( i.ToString() ); 6i++; 7}  8 long  EndTime   =  DateTime.Now.Ticks;  9 10 Console.WriteLine(  " 时间: "   +  ( EndTime - StartTime ) ); 11 12 string  sb1  =   null ; 13 =   0 ; 14 StartTime   =  DateTime.Now.Ticks; 15 while  ( i  <   100000  )  16 {17sb1 += i;18i++;19} 20 EndTime   =  DateTime.Now.Ticks; 21 Console.WriteLine(  " 时间: "   +  ( EndTime - StartTime ));

    最新回复(0)