1、字符串(string)的不可变性:当重新给字符串赋值,老值并没有销毁,而是重新开辟一块新的内存来存储新值。
值类型:当定义一个整形变量 Int n1 = 10;系统会在栈中开辟一块内存空间,存储10,当再次赋值n1=20;则栈
中不会再开辟新的内存空间,只会在原来的空间上把10替换成20,此时10不存在了。
→ → →→
上开辟一块内存空间存储"张三"在堆中的地址(s1=0x001001),此时s1指向“张三” ;当重新给字符串赋值之后,s1=“孙全”;系统会重新在堆上开辟一块新的内存空间来存储“孙全”,原来堆上内存空间中的“张三”仍然存在;同时栈上s1存储的值变成“孙全”在堆上的地址(s1=0x010101),此时s1指向“孙全”。这就是字符串的不可变性。引用类型:而当定义一个字符串变量string s1= "张三";系统会在堆中开辟一块内存空间,存储“张三”,同时在栈
→ →
圾回收器)会扫描整个内存,当发现有的内存空间没有被指向时,则立刻将其销毁。由于字符串的不可变性,导致字符串重新赋值之后,原来的值就会变成内存中的垃圾。当程序结束之后,GC(垃
2、当程序中多次出现字符串的拼接或赋值操作时,将会产生大量的内存垃圾。此时,可以使用StringBuilder来解决:
<span style="font-size:18px;">string str = null;
Stopwatch sw = new Stopwatch(); // 创建一个计时器对象,用来记录程序运行的时间
sw.Start(); // 开始计时
for (int i = 0; i < 100000; i++)
{
str += i; // 字符串的重复拼接,产生大量的垃圾。
}
sw.Stop(); // 结束计时
Console.WriteLine(sw.Elapsed); // 00:00:17.4497019 时间比较长</span>
当使用StringBuilder时:
<span style="font-size:18px;">StringBuilder sb = new StringBuilder();
sw.Start();
for (int i = 0; i < 100000; i++)
{
sb.Append(i); // 追加
}
sw.Stop();
Console.WriteLine(sw.Elapsed); // 00:00:00.0197216 时间非常短</span>
3、字符串可以看成只读类型的char数组:
string s = "abcdefg";
Console.Writeline(s[0]); // s[0] = 'a';
s[0] = 'b';// 此写法错误,因为是只读的。
char[] chs = s.ToCharArray(); // 可以将字符串转换成char数组:
chs[0] = 'b'; // 此时可以给char数组赋值
s = new string(chs); // 将char数组转换成一个字符串
Console.WriteLine(s); // s = "bbcdefg";
4、字符串的常用方法:
Length:字符串的字符个数。
ToUpper():将字符串转换成大写。
ToLower():将字符串转换成小写。
Equals():比较字符串。
string str1 = "chen";
string str2 = "CHEN";
if (str1.Equals(str2, StringComparison.OrdinalIgnoreCase)) // 忽略大小写比较
{
Console.WriteLine("字符串相等");
}
分割字符串:
string s = "ab d + , op- = qq";
char[] chs = {' ', '+', ',', '-', '='};
string[] strs = s.Split(chs); // 把char数组里的字符全部变成空值
string[] strs = s.Split(chs, StringSplitOptions.RemoveEmptyEntries); // 去掉char数组里的字符,空值也去掉
Contains():判断字符串中是否存在某个子串
Replace():用指定的字符串替换某个字符串
string str = "国家关键人物老张";
if (str.Contains("老张")) // 如果字符串中存在子串"老张"
{
str = str.Replace("老张", "**"); // 用 "**" 替换 "老张"
}
Substring:截取字符串
Substring(2):从指定的位置开始截取,直到最后。
Substring(2, 3):从指定的位置开始,截取指定长度的子串。
StartsWith():判断字符串是否以指定的子串开始
EndsWith():判断字符串是否以指定的子串结尾
IndexOf():查找指定的字符或子串在字符串中第一次出现的位置,返回指定字符的索引
IndexOf(char, int):从指定位置开始查找指定字符或子串的索引
LastIndexOf():查找指定字符或子串在字符串中最后一次出现的位置
Trim():去除字符串中前面和后面的空格
TrimEnd():去除字符串中后面的空格
TrimStart():去除字符串中前面的空格
IsNullOrEmpty():判断字符串是否为空
string str = "";
if (string.IsNullOrEmpty(str))
{
Console.WriteLine("字符串为空");
}
Join():用指定的分隔符分割字符串
string[] strNames = {"张三", "李四", "王五", "赵六", "田七"};
string strName = string.Join("|", strNames);// strName = "张三|李四|王五|赵六|田七";