StringBuilder的实现与技巧ZZ
在上一篇进一步了解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 ));
StringBuilder的实现与技巧ZZ的更多相关文章
- StringBuilder的实现与技巧(转)
1.Length 0.说明 在上一篇进一步了解String 中,发现了string的不便之处,而string的替代解决方案就是StringBuilder的使用 它的使用也很简单 System.Te ...
- 深入理解Java中的String
一.String类 想要了解一个类,最好的办法就是看这个类的实现源代码,来看一下String类的源码: public final class String implements java.io.Ser ...
- Java总结篇系列:Java String
String作为Java中最常用的引用类型,相对来说基本上都比较熟悉,无论在平时的编码过程中还是在笔试面试中,String都很受到青睐,然而,在使用String过程中,又有较多需要注意的细节之处. 1 ...
- C#自学笔记总结
一.变量:声明变量的语法:变量类型 变量名; 变量名=值;变量类型 变量名=值: 在使用变量的时候要注意:变量一定要先声明,再赋值,最后使用例子: 变量的特点:1.不能够被重复的声明2.可以被重复的赋 ...
- 跟着刚哥梳理java知识点——深入理解String类(九)
一.String类 想要了解一个类,最好的办法就是看这个类的实现源代码,来看一下String类的源码: public final class String implements java.io.Ser ...
- 【转】深入理解Java中的String
原文链接:http://www.cnblogs.com/xiaoxi/p/6036701.html 一.String类 想要了解一个类,最好的办法就是看这个类的实现源代码,来看一下String类的源码 ...
- String的解析
String作为Java中最常用的引用类型,相对来说基本上都比较熟悉,无论在平时的编码过程中还是在笔试面试中,String都很受到青睐,然而,在使用String过程中,又有较多需要注意的细节之处. 1 ...
- 聊聊c#字符串拼接
字符串对我编程人员来说是字符串时每天见面的常客,你不认识不熟悉他都不得行,字符串的拼接更是家常便饭,那么在实际开发过程中实现字符串的拼接有哪一些方式呢?咱们一起来聊聊,来交流沟通,学习一波.也许你会说 ...
- java字符串拼接技巧(StringBuilder使用技巧)
在平时的开发中,我们可能会遇到需要拼接如下格式的字符串(至少我是遇到了很多次): 1,2,3,4,5,6,7,8,9,10,11,12,12,12,12,34,234,2134,1234,1324,1 ...
随机推荐
- bzoj千题计划296:bzoj1053: [HAOI2007]反素数ant
http://www.lydsy.com/JudgeOnline/problem.php?id=1053 求n以内约数个数最多的数 #include<cstdio> using names ...
- CF876 D 树状数组
大意就是放n个硬币,每次放一个计算下这种情况下的操作次数,一个操作为从左到右扫描,如果一个硬币右边是空的,就将硬币后移,否则该次操作停止. 显然发现对于一个情况,我们只要考虑最右边的空位的左侧有几个硬 ...
- Lua程序设计(二)面向对象概念介绍
----------------------------------------------------------- Lua面向对象3 local smartMan = { name = " ...
- 一个ssm综合小案例-商品订单管理----写在前面
学习了这么久,一直都是零零散散的,没有把知识串联起来综合运用一番 比如拦截器,全局异常处理,json 交互,RESTful 等,这些常见技术必须要掌握 接下来呢,我就打算通过这么一个综合案例把这段时间 ...
- 【问题收集·知识储备】Xcode只能选择My Mac,不能选择模拟器如何解决?
网友问题:请问打开一个应用,只能选择My Mac,不能选择模拟器如何解决? 答案: 下面将问答过程记录如下: CHENYILONG Blog 请问打开一个应用,只能 ...
- CF232C Doe Graphs
传送门 Solution: (不理解时对着图研究一下就清楚啦!!!) sm[i]为|D(i)| (x,y,n)为x,y在D(n)中的最短路 已知sm[i-1]+1为D(i)的割点 于是x-y的最短 ...
- Zookeeper命名服务——生成分布式有序且唯一id
生成分布式有序且唯一id的方法有很多种,使用zookeeper是比较简单的一种方法,只是生成的速度不高,这里只是一个借助zk的版本号生成分布式唯一且有序id的例子. ZkIdGenerator.jav ...
- ACM数据对拍程序
#include<cstdio> #include<cstdlib> #include<ctime> int main() { long s,t; while(1) ...
- linux笔记_day10_shell编程
1.shell编程 编程语言 静态语言:编译型语言 强类型(变量在使用前,必须事先声明) 事先转换成可执行语言 动态语言:解释型语言 弱类型(变量用时声明,拿来直接用,甚至不区分数据类型,一般默认都为 ...
- Windows命令-系统木马取样
1.前言 工作中偶尔会遇到去现场提取木马样本回公司分析的情况.如果是生产环境下,不方便安装各类抓包.安全软件时.能用系统自带的命令去定位出木马程序相关的信息是最理想不过的状态. 2.Windows常用 ...