打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
StringBuilder的实现与技巧

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

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;
}
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 ) {
 5
sb.Append( i.ToString() );
 6
i++;
 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
i = 0;
16
StartTime  = DateTime.Now.Ticks;
17
while ( i < 100000 ) 
18
{
19
if ( sb1.Capacity <= sb1.Length )//先判断是否>Length
20
sb1.Capacity += 7;//这里一定要根据情况的增加容量,否则会有性能上的消耗
21
sb1.Append( i.ToString() );
22
i++;
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 ) {
 5
sb.Append( i.ToString() );
 6
i++;
 7
}
 8
long EndTime  = DateTime.Now.Ticks;
 9

10
Console.WriteLine( "时间:" + ( EndTime-StartTime ) );
11

12
string sb1 = null;
13
i = 0;
14
StartTime  = DateTime.Now.Ticks;
15
while ( i < 100000 ) 
16
{
17
sb1 += i;
18
i++;
19
}
20
EndTime  = DateTime.Now.Ticks;
21
Console.WriteLine( "时间:" + ( EndTime-StartTime ));



本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
字符串处理总结之二(C#StringBuilder类)
分解质因数
C#中的多线程使用
java设计模式之具体体现
使用StringBuilder, StringBuilder和String的区别 - 专注...
ASP.NET夜话之二十一asp.net网站的性能优化 - worm128的日志 - 网易...
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服