* 由于字符串的相加会产生了一个新的字符串,当有多个字符串相加时,就会不断的有字符串构造出来和被析构掉,当然这是相当耗资源的。
* 所以就有了StringBuilder类。
* StringBuilder的实现方式是这样的,默认分配16个字节的空间,如果追加的字符个数超过当前分配的空间,
* 系统就重新分配一块两倍的空间,16,,32,64,128,256....。再把字符串的值拷贝到新的内存中。以前的内存等着垃圾回收器回收。
* 这样也会有大量的内存被分配和回收。
* 但StringBuilder可没有那么笨,它可以分配指定大小的连续内存用于存储字符串,如果指定的内存大小刚好容纳所有的字符串,
* 那就不会有多余的内存分配和回收,所以在使用StringBuilder的时候,如果能估计将要存放的字符个数的话,分配恰当的内存,
* 将会大大的提高程序的性能,可惜的是(个人认为)很多程序员在使用StringBuilder的时候都没有预分配内存。
* 它用一个字符数组存放字符串,每次追加字符串的时候,都是往数组的后面追加字符串,
* 所以操作字符串中指定的字符非常方便,读取所有字符串也很快。
* 以下是我自己写的精简版的StringBuilder类。
* 个人认为微软实现的方式跟我的差不多,由于本人技术有限(只是比较喜欢技术),没有遇到技术非常牛逼的人,也没有看过非常牛逼的代码,
* 开源的代码看得好累,有点不知所云,所以我暂时还很难写出较好的代码,以下代码肯定漏洞百出,
* 以下代码我自己还是用了点时间写的,对于程序的初学者来说应该有点帮助,
* 希望程序大牛千万不要手软,多加批评,多加指导,我定虚心认真学习 源码下载
源码
1 using System;
2
3 namespace CthSoft
4 {
5 public class StringBuilder
6 {
属性
1 #region 属性
2 char[] strBuf;//存储字符串的字符数组
3
4 private int capacity=16;//字符数组的容量
5 public int Capacity
6 {
7 get { return capacity; }
8 set
9 {
10 SetCapacity(value);
11 this.capacity = value;
12 }
13 }
14
15 private int length;//字符串的长度
16 public int Length
17 {
18 get { return length; }
19 set
20 {
21 //字符串长度不能小于0
22 if (value < 0)
23 {
24 throw new ArgumentOutOfRangeException("长度不能小于 0。参数名: length");
25 }
26
27 if (value == capacity)
28 {
29 return;
30 }
31
32 if (value > capacity)
33 {
34 this.Capacity = value;
35 }
36 else
37 {
38 for (int i = value; i < length; i++)
39 {
40 strBuf[i] = '\0';
41 }
42 }
43
44 this.length = value;
45 }
46 }
47
48 //字符数组的最大容量,即int类型的最大值(容量是int类型)
49 private int maxCapacity = int.MaxValue;
50 public int MaxCapacity
51 {
52 set { maxCapacity = value; }
53 get { return maxCapacity; }
54 }
55 #endregion
辅助方法
1 #region 辅助方法
2 private void SetCapacity(int value)
3 {
4 CheckCapacitySize(value,this.maxCapacity);
5 if (strBuf != null)
6 {
7 char[] tmpBuf = new char[value];
8 Array.Copy(strBuf, tmpBuf, strBuf.Length);
9 strBuf = tmpBuf;
10 tmpBuf = null;
11 }
12 else {
13 strBuf = new char[value];
14 }
15 }
16
17 private void SetCapacity()
18 {
19 if (this.length > this.capacity)
20 {
21 while (this.length > this.capacity)
22 {
23 this.capacity = this.capacity << 1;
24 }
25 SetCapacity(this.capacity);
26 }
27 }
28
29 private void CheckCapacitySize(int capacity, int maxCapacity)
30 {
31 CheckRange(capacity);
32 CheckRange(maxCapacity);
33 if (maxCapacity < capacity)
34 {
35 throw new ArgumentOutOfRangeException("容量超出了最大容量。参数名: capacity");
36 }
37 }
38
39 private void CheckRange(int index)
40 {
41 if (index < 0)
42 {
43 throw new IndexOutOfRangeException("索引超出了数组界限。参数名: index");
44 }
45 }
46
47 private void CheckRange(int index, int count)
48 {
49 CheckRange(index);
50 CheckRange(count);
51 CheckRange(index + count);
52 }
53 #endregion
初始化
1 #region 初始化
2 private void Initializtion(int length)
3 {
4 strBuf = new char[this.capacity];
5 this.length = length;
6 }
7
8 private void Initializtion(ref string value)
9 {
10 if (value == null)
11 {
12 Initializtion(0);
13 }
14 else
15 {
16 while (value.Length > this.capacity)
17 {
18 this.capacity = this.capacity << 1;
19 }
20 Initializtion(value.Length);
21 Array.Copy(value.ToCharArray(), strBuf, value.Length);
22 }
23 }
24
25 private void Initializtion(ref string value,int capacity)
26 {
27 CheckRange(capacity);
28 this.capacity = capacity;
29 Initializtion(ref value);
30 }
31 #endregion
构造函数
1 #region 构造函数
2 public StringBuilder()
3 {
4 Initializtion(0);
5 }
6
7 public StringBuilder(string value)
8 {
9 Initializtion(ref value);
10 }
11
12 public StringBuilder(string value, int capacity)
13 {
14 Initializtion(ref value,capacity);
15 }
16
17 public StringBuilder(int capacity)
18 {
19 string value = null;
20 Initializtion(ref value, capacity);
21 }
22
23 public StringBuilder(int capacity, int maxCapacity)
24 {
25 CheckCapacitySize(capacity,maxCapacity);
26 this.capacity = capacity;
27 this.maxCapacity = maxCapacity;
28 Initializtion(0);
29 }
30
31 public StringBuilder(string value, int startIndex, int length, int capacity)
32 {
33 if (startIndex < 0 || length < 0 || startIndex >= value.Length || startIndex + length >= value.Length)
34 {
35 throw new ArgumentOutOfRangeException("索引和长度必须引用该字符串内的位置");
36 }
37 value = value.Substring(startIndex, length);
38 Initializtion(ref value, capacity);
39 }
40 #endregion
Append
1 #region Append
2 public StringBuilder Append(char[] value)
3 {
4 return Append(value,0,value.Length);
5 }
6
7 public StringBuilder Append(string value)
8 {
9 if (value == null)
10 {
11 value = string.Empty;
12 }
13 Append(value.ToCharArray());
14 return this;
15 }
16
17 public StringBuilder Append(object value)
18 {
19 if (value == null)
20 {
21 value = string.Empty;
22 }
23 Append(value.ToString().ToCharArray());
24 return this;
25 }
26
27 public StringBuilder Append(int value)
28 {
29 Append(value.ToString().ToCharArray());
30 return this;
31 }
32
33 public StringBuilder Append(byte value)
34 {
35 Append(value.ToString().ToCharArray());
36 return this;
37 }
38
39 public StringBuilder Append(long value)
40 {
41 Append(value.ToString().ToCharArray());
42 return this;
43 }
44
45 public StringBuilder Append(float value)
46 {
47 Append(value.ToString().ToCharArray());
48 return this;
49 }
50
51 public StringBuilder Append(double value)
52 {
53 Append(value.ToString().ToCharArray());
54 return this;
55 }
56
57 public StringBuilder Append(decimal value)
58 {
59 Append(value.ToString().ToCharArray());
60 return this;
61 }
62
63 public StringBuilder Append(bool value)
64 {
65 if (value)
66 {
67 Append("True".ToCharArray());
68 }
69 else {
70 Append("False".ToCharArray());
71 }
72 return this;
73 }
74
75 public StringBuilder Append(char value, int repeatCount)
76 {
77 if (repeatCount < 0)
78 {
79 throw new ArgumentOutOfRangeException("字符的数量必须大于零,参数repeatCount");
80 }
81 char[] tmpBuf = new char[repeatCount];
82 for (int i = 0; i < repeatCount; i++)
83 {
84 tmpBuf[i] = value;
85 }
86 return Append(tmpBuf);
87 }
88
89 public StringBuilder Append(char[] value, int startIndex, int charCount)
90 {
91 if (value == null)
92 {
93 value = new char[] { '\0' };
94 }
95 if (startIndex < 0 || charCount < 0 || startIndex + charCount > value.Length)
96 {
97 throw new IndexOutOfRangeException("索引超出了数组界限。参数名: index");
98 }
99 this.length = this.length + charCount;
100 SetCapacity();
101 Array.Copy(value, startIndex, strBuf, this.length - value.Length, charCount);
102 return this;
103 }
104
105
106 public StringBuilder AppendFormat(string format, object arg0)
107 {
108 return Append(string.Format(format, arg0));
109 }
110
111 public StringBuilder AppendFormat(string format, params object[] args)
112 {
113 return Append(string.Format(format, args));
114 }
115
116 public StringBuilder AppendFormat(string format, object arg0, object arg1)
117 {
118 return Append(string.Format(format, arg0,arg1));
119 }
120
121 public StringBuilder AppendFormat(string format, object arg0, object arg1, object arg2)
122 {
123 return Append(string.Format(format, arg0, arg1,arg2));
124 }
125 #endregion
Insert
1 #region Insert
2 public StringBuilder Insert(int index, char[] value)
3 {
4 if (value == null)
5 {
6 return this;
7 }
8 if (index < 0 || index > this.length)
9 {
10 throw new IndexOutOfRangeException("索引超出了数组界限。参数名: index");
11 }
12
13 this.length = this.length + value.Length;
14 if (this.length > this.capacity)
15 {
16 SetCapacity(this.length);
17 }
18
19 for (int i = this.length-1-value.Length; i >=index ; i--)
20 {
21 strBuf[i + value.Length] = strBuf[i];
22 }
23 for (int i = 0; i < value.Length; i++)
24 {
25 strBuf[index + i] = value[i];
26 }
27
28 return this;
29 }
30
31 public StringBuilder Insert(int index, string value)
32 {
33 if (value == null)
34 {
35 return this;
36 }
37 return Insert(index,value.ToCharArray());
38 }
39
40 public StringBuilder Insert(int index, byte value)
41 {
42 return Insert(index, value.ToString().ToCharArray());
43 }
44
45 public StringBuilder Insert(int index, char value)
46 {
47 CheckRange(index);
48 this.length++;
49 if (this.length > this.capacity)
50 {
51 SetCapacity(this.length);
52 }
53
54 for (int i = this.length - 2; i >= index; i--)
55 {
56 strBuf[i + 1] = strBuf[i];
57 }
58 strBuf[index] = value;
59 return this;
60 }
61
62 public StringBuilder Insert(int index, int value)
63 {
64 return Insert(index, value.ToString().ToCharArray());
65 }
66
67 public StringBuilder Insert(int index, long value)
68 {
69 return Insert(index, value.ToString().ToCharArray());
70 }
71
72 public StringBuilder Insert(int index, double value)
73 {
74 return Insert(index, value.ToString().ToCharArray());
75 }
76
77 public StringBuilder Insert(int index, object value)
78 {
79 return Insert(index, value.ToString().ToCharArray());
80 }
81
82 public StringBuilder Insert(int index, short value)
83 {
84 return Insert(index, value.ToString().ToCharArray());
85 }
86
87 public StringBuilder Insert(int index, decimal value)
88 {
89 return Insert(index, value.ToString().ToCharArray());
90 }
91
92 public StringBuilder Insert(int index, float value)
93 {
94 return Insert(index, value.ToString().ToCharArray());
95 }
96
97 public StringBuilder Insert(int index, string value, int count)
98 {
99 if (value == null)
100 {
101 return this;
102 }
103 CheckRange(index);
104 if (count < 0)
105 {
106 throw new ArgumentOutOfRangeException("index 小于零或大于此实例的当前长度。- 或 - count 小于零");
107 }
108 if (value.Length * count+this.length > this.maxCapacity)
109 {
110 throw new OutOfMemoryException("对象的当前长度加上 value 的长度乘以 count 的值超过StringBuilder.MaxCapacity。");
111 }
112 char[] tmpBuf = new char[value.Length * count];
113 for (int i = 0; i < count; i++)
114 {
115 Array.Copy(value.ToCharArray(),0,tmpBuf, value.Length*i,value.Length);
116 }
117 Insert(index,tmpBuf);
118 tmpBuf = null;
119 return this;
120 }
121
122 public StringBuilder Insert(int index, char[] value, int startIndex, int charCount)
123 {
124 if (value == null || value.Length == 0)
125 {
126 return this;
127 }
128
129 if (index<0 || charCount<0 ||startIndex + charCount>value.Length)
130 {
131 throw new IndexOutOfRangeException("索引超出了数组界限。参数名: charCount");
132 }
133
134 char[] tmpBuf = new char[charCount];
135 Array.Copy(value,startIndex,tmpBuf,0,charCount);
136 Insert(index, tmpBuf);
137 tmpBuf = null;
138 return this;
139 }
140
141
142
143 #endregion
Remove
1 #region remove
2 public StringBuilder Remove(int startIndex, int length)
3 {
4 CheckRange(startIndex , length);
5
6 for (int i = startIndex + length; i < this.length; i++)
7 {
8 strBuf[startIndex++] = strBuf[i];
9 }
10 for (int i = startIndex; i < this.length; i++)
11 {
12 strBuf[i] = '\0';
13 }
14 this.length = this.length - length;
15 return this;
16 }
17
18 public StringBuilder Remove(char[] value)
19 {
20 if (value == null || value.Length > this.length)
21 {
22 return this;
23 }
24 int k,t;
25 for (int i = 0; i < this.length; i++)
26 {
27 if (value[0] == strBuf[i])
28 {
29 k = i;
30 t=0;
31 while (k < this.length && t < value.Length)
32 {
33 if (value[t++] != strBuf[k++])
34 {
35 break;
36 }
37
38 if (t == value.Length)
39 {
40 return Remove(i, t);
41 }
42 }
43 }
44 }
45 return this;
46 }
47
48 public StringBuilder Remove(string value)
49 {
50 if (value == null)
51 {
52 return this;
53 }
54 return Remove(value.ToCharArray());
55 }
56
57 public StringBuilder RemoveAll(string value)
58 {
59 if (value == null || value.Length > this.length)
60 {
61 return this;
62 }
63 int k, t;
64 for (int i = 0; i < this.length; i++)
65 {
66 if (value[0] == strBuf[i])
67 {
68 k = i;
69 t = 0;
70 while (k < this.length && t < value.Length)
71 {
72 if (value[t++] != strBuf[k++])
73 {
74 break;
75 }
76
77 if (t == value.Length)
78 {
79 Remove(i, t);
80 break;
81 }
82 }
83 }
84 }
85 return this;
86 }
87 #endregion
Replace
1 #region replace
2 public StringBuilder Replace(char oldChar, char newChar)
3 {
4 for (int i = 0; i < strBuf.Length;i++ )
5 {
6 if (strBuf[i] == oldChar)
7 {
8 strBuf[i] = newChar;
9 }
10 }
11 return this;
12 }
13
14 public StringBuilder Replace(char oldChar, char newChar, int startIndex, int count)
15 {
16 CheckRange(startIndex , length);
17
18 for (int i = startIndex; i < startIndex + count; i++)
19 {
20 if (strBuf[i] == oldChar)
21 {
22 strBuf[i] = newChar;
23 }
24 }
25 return this;
26 }
27
28 public StringBuilder Replace(string oldValue, string newValue)
29 {
30 return Replace(oldValue,newValue,0,this.length);
31 }
32
33 public StringBuilder Replace(string oldValue, string newValue, int startIndex, int count)
34 {
35 CheckRange(startIndex , count);
36 if (oldValue == null || oldValue.Length > this.length)
37 {
38 return this;
39 }
40
41 if (newValue == null)
42 {
43 newValue = string.Empty;
44 }
45
46 int i, k;
47 bool isChange = false;
48 for (int j = startIndex; j < startIndex+count; j++)
49 {
50 if (oldValue[0] == strBuf[j])
51 {
52 k = j;
53 i = 0;
54 while (i <= oldValue.Length && k <= this.length)
55 {
56 if (oldValue[i++] != strBuf[k++])
57 {
58 break;
59 }
60 if (i == oldValue.Length)
61 {
62 i = 0;
63 k = j;
64 while (i < oldValue.Length && i < newValue.Length)
65 {
66 strBuf[k++] = newValue[i++];
67 }
68
69 if (newValue.Length > i)
70 {
71 Insert(i, newValue.Substring(i));
72 }
73 else if (oldValue.Length > i)
74 {
75 Remove(k, oldValue.Length - i);
76 }
77 isChange = true;
78 break;
79 }
80 }
81 if (isChange)
82 {
83 j = j + Math.Min(oldValue.Length , newValue.Length)-1;
84 isChange = false;
85 }
86 }
87 }
88 return this;
89 }
90
91 #endregion
ToString
1 public char this[int index]
2 {
3 set
4 {
5 CheckRange(index);
6 strBuf[index] = value;
7 }
8 get
9 {
10 CheckRange(index);
11 return strBuf[index];
12 }
13 }
14
15 public override string ToString()
16 {
17 return new string(strBuf);
18 }
19
20 public string ToString(int startIndex, int length)
21 {
22 CheckRange(startIndex,length);
23 char[] tmpBuf = new char[length];
24 Array.Copy(strBuf,startIndex,tmpBuf,0,length);
25 return new string(tmpBuf);
26 }
27
28 }
29 }