在上一篇进一步了解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
![None.gif](/Images/OutliningIndicators/None.gif)
2
![None.gif](/Images/OutliningIndicators/None.gif)
3
![None.gif](/Images/OutliningIndicators/None.gif)
4
![None.gif](/Images/OutliningIndicators/None.gif)
5
![None.gif](/Images/OutliningIndicators/None.gif)
6
![None.gif](/Images/OutliningIndicators/None.gif)
7
![None.gif](/Images/OutliningIndicators/None.gif)
8
![None.gif](/Images/OutliningIndicators/None.gif)
通过上面的代码,我们可以看出如果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![None.gif](/Images/OutliningIndicators/None.gif)
5
sb.Append(
'
1
'
,
17
);
//
添加一个字符串,这里故意添加17个字符,是为了看到Capacity是如何被扩充的
6
Console.Write(
"
Capacity:
"
+
sb.Capacity );
//
这里的Capacity会自动扩大
7
Console.WriteLine(
"
\t Length:
"
+
sb.Length );
8![None.gif](/Images/OutliningIndicators/None.gif)
9
sb.Append(
'
2
'
,
32
);
//
添加一个字符串
10
Console.Write(
"
Capacity:
"
+
sb.Capacity );
//
这里的Capacity会自动扩大
11
Console.WriteLine(
"
\t Length:
"
+
sb.Length );
12![None.gif](/Images/OutliningIndicators/None.gif)
13
sb.Append(
'
3
'
,
64
);
//
添加一个字符串
14
Console.Write(
"
Capacity:
"
+
sb.Capacity );
//
这里的Capacity会自动扩大
15
Console.WriteLine(
"
\t Length:
"
+
sb.Length );
16![None.gif](/Images/OutliningIndicators/None.gif)
17
//
注意这里:如果你取消Remove这步操作,将会引发ArgumentOutOfRangeException异常,因为当前容量小于
18
19
//Length,这在自己控制StringBuilder的时候务必要注意容量溢出的问题
20![None.gif](/Images/OutliningIndicators/None.gif)
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![None.gif](/Images/OutliningIndicators/None.gif)
27
sb.Append(
'
b
'
,
4
);
28
Console.Write(
"
Capacity:
"
+
sb.Capacity );
//
这里的Capacity会自动扩大
29
Console.WriteLine(
"
\t Length:
"
+
sb.Length );
30![None.gif](/Images/OutliningIndicators/None.gif)
31
sb.Append(
'
c
'
,
6
);
32
Console.Write(
"
Capacity:
"
+
sb.Capacity );
//
这里的Capacity会自动扩大
33
Console.WriteLine(
"
\t Length:
"
+
sb.Length
![None.gif](/Images/OutliningIndicators/None.gif)
2
![None.gif](/Images/OutliningIndicators/None.gif)
3
![None.gif](/Images/OutliningIndicators/None.gif)
4
![None.gif](/Images/OutliningIndicators/None.gif)
5
![None.gif](/Images/OutliningIndicators/None.gif)
6
![None.gif](/Images/OutliningIndicators/None.gif)
7
![None.gif](/Images/OutliningIndicators/None.gif)
8
![None.gif](/Images/OutliningIndicators/None.gif)
9
![None.gif](/Images/OutliningIndicators/None.gif)
10
![None.gif](/Images/OutliningIndicators/None.gif)
11
![None.gif](/Images/OutliningIndicators/None.gif)
12
![None.gif](/Images/OutliningIndicators/None.gif)
13
![None.gif](/Images/OutliningIndicators/None.gif)
14
![None.gif](/Images/OutliningIndicators/None.gif)
15
![None.gif](/Images/OutliningIndicators/None.gif)
16
![None.gif](/Images/OutliningIndicators/None.gif)
17
![None.gif](/Images/OutliningIndicators/None.gif)
18
![None.gif](/Images/OutliningIndicators/None.gif)
19
![None.gif](/Images/OutliningIndicators/None.gif)
20
![None.gif](/Images/OutliningIndicators/None.gif)
21
![None.gif](/Images/OutliningIndicators/None.gif)
22
![None.gif](/Images/OutliningIndicators/None.gif)
23
![None.gif](/Images/OutliningIndicators/None.gif)
24
![None.gif](/Images/OutliningIndicators/None.gif)
25
![None.gif](/Images/OutliningIndicators/None.gif)
26
![None.gif](/Images/OutliningIndicators/None.gif)
27
![None.gif](/Images/OutliningIndicators/None.gif)
28
![None.gif](/Images/OutliningIndicators/None.gif)
29
![None.gif](/Images/OutliningIndicators/None.gif)
30
![None.gif](/Images/OutliningIndicators/None.gif)
31
![None.gif](/Images/OutliningIndicators/None.gif)
32
![None.gif](/Images/OutliningIndicators/None.gif)
33
![None.gif](/Images/OutliningIndicators/None.gif)
上面的代码输出的结果:
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
![None.gif](/Images/OutliningIndicators/None.gif)
2
![None.gif](/Images/OutliningIndicators/None.gif)
3
![None.gif](/Images/OutliningIndicators/None.gif)
4
![None.gif](/Images/OutliningIndicators/None.gif)
5
![None.gif](/Images/OutliningIndicators/None.gif)
6
![None.gif](/Images/OutliningIndicators/None.gif)
7
![None.gif](/Images/OutliningIndicators/None.gif)
从上面的代码和结果可以说明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![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
while
( i
<
100000
)
{
5
sb.Append( i.ToString() );
6
i++;
7
}
8
long
EndTime
=
DateTime.Now.Ticks;
9![None.gif](/Images/OutliningIndicators/None.gif)
10
Console.WriteLine(
"
时间:
"
+
( EndTime
-
StartTime )
+
"
\t Capacity:
"
+
sb.Capacity
+
"
\t Length:
"
11![None.gif](/Images/OutliningIndicators/None.gif)
12
+
sb.Length);
13![None.gif](/Images/OutliningIndicators/None.gif)
14
System.Text.StringBuilder sb1
=
new
System.Text.StringBuilder();
15
i
=
0
;
16
StartTime
=
DateTime.Now.Ticks;
17
while
( i
<
100000
)
18![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
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![None.gif](/Images/OutliningIndicators/None.gif)
26
Console.WriteLine(
"
时间:
"
+
( EndTime
-
StartTime )
+
"
\t Capacity:
"
+
sb1.Capacity
+
"
\t
27
28
Length:
"
+ sb1.Length);
需要特别说明的一点是,自动增加的容量,一定要根据实际预见的情况而改变,否则不但起不到优化的作用,反而会影响到程序的性能..
![None.gif](/Images/OutliningIndicators/None.gif)
2
![None.gif](/Images/OutliningIndicators/None.gif)
3
![None.gif](/Images/OutliningIndicators/None.gif)
4
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
5
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
6
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
7
![ExpandedBlockEnd.gif](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
8
![None.gif](/Images/OutliningIndicators/None.gif)
9
![None.gif](/Images/OutliningIndicators/None.gif)
10
![None.gif](/Images/OutliningIndicators/None.gif)
11
![None.gif](/Images/OutliningIndicators/None.gif)
12
![None.gif](/Images/OutliningIndicators/None.gif)
13
![None.gif](/Images/OutliningIndicators/None.gif)
14
![None.gif](/Images/OutliningIndicators/None.gif)
15
![None.gif](/Images/OutliningIndicators/None.gif)
16
![None.gif](/Images/OutliningIndicators/None.gif)
17
![None.gif](/Images/OutliningIndicators/None.gif)
18
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
19
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
20
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
21
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
22
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
23
![ExpandedBlockEnd.gif](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
24
![None.gif](/Images/OutliningIndicators/None.gif)
25
![None.gif](/Images/OutliningIndicators/None.gif)
26
![None.gif](/Images/OutliningIndicators/None.gif)
27
![None.gif](/Images/OutliningIndicators/None.gif)
28
![None.gif](/Images/OutliningIndicators/None.gif)
另外,如果有时间的话,可以测试一下下面的代码,用string和StringBuilder拼接字符串的区别..你会吓到的!!
1
System.Text.StringBuilder sb
=
new
System.Text.StringBuilder();
2
int
i
=
0
;
3
long
StartTime
=
DateTime.Now.Ticks;
4![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
while
( i
<
100000
)
{
5
sb.Append( i.ToString() );
6
i++;
7
}
8
long
EndTime
=
DateTime.Now.Ticks;
9![None.gif](/Images/OutliningIndicators/None.gif)
10
Console.WriteLine(
"
时间:
"
+
( EndTime
-
StartTime ) );
11![None.gif](/Images/OutliningIndicators/None.gif)
12
string
sb1
=
null
;
13
i
=
0
;
14
StartTime
=
DateTime.Now.Ticks;
15
while
( i
<
100000
)
16![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
17
sb1 += i;
18
i++;
19
}
20
EndTime
=
DateTime.Now.Ticks;
21
Console.WriteLine(
"
时间:
"
+
( EndTime
-
StartTime ));
![None.gif](/Images/OutliningIndicators/None.gif)
2
![None.gif](/Images/OutliningIndicators/None.gif)
3
![None.gif](/Images/OutliningIndicators/None.gif)
4
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
5
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
6
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
7
![ExpandedBlockEnd.gif](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
8
![None.gif](/Images/OutliningIndicators/None.gif)
9
![None.gif](/Images/OutliningIndicators/None.gif)
10
![None.gif](/Images/OutliningIndicators/None.gif)
11
![None.gif](/Images/OutliningIndicators/None.gif)
12
![None.gif](/Images/OutliningIndicators/None.gif)
13
![None.gif](/Images/OutliningIndicators/None.gif)
14
![None.gif](/Images/OutliningIndicators/None.gif)
15
![None.gif](/Images/OutliningIndicators/None.gif)
16
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](/Images/OutliningIndicators/ContractedBlock.gif)
![dot.gif](https://www.cnblogs.com/Images/dot.gif)
17
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
18
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
19
![ExpandedBlockEnd.gif](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
20
![None.gif](/Images/OutliningIndicators/None.gif)
21
![None.gif](/Images/OutliningIndicators/None.gif)