zoukankan      html  css  js  c++  java
  • 自己写的精简版StringBuilder类 附源码

     * 由于字符串的相加会产生了一个新的字符串,当有多个字符串相加时,就会不断的有字符串构造出来和被析构掉,当然这是相当耗资源的。
     * 所以就有了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 }
     
  • 相关阅读:
    html的URL参数传值问题
    html背景图片拉伸至全屏
    Laravel 用户验证Auth::attempt fail的问题
    HTML中meta的应用
    ubuntu升级php版本
    Laravel 目录结构分析
    css颜色渐变在不同浏览器的设置
    谷歌浏览器(Chrome)离线包的下载方法!
    RAD Studio 10 up1欢迎页证书不可用
    MySQL
  • 原文地址:https://www.cnblogs.com/hlxs/p/StringBuilder.html
Copyright © 2011-2022 走看看