25.String

25.面向对象关联知识点-String


25.1 知识点

string字符串类概述

  • Stringstring 类的别名,两者都可以使用,类似于 Objectobject
  • 示例:
string string1 = "string1";
String String1 = "String1";
  • 字符串是用于表示文本的字符的顺序集合。
  • 对象 String 是表示字符串的 System.Char 对象的连续集合;System.Char 对象对应于 UTF-16 代码单元。
  • 对象的值 String 是对象的顺序集合 System.Char 的内容,该值是不可变的(也就是说,它是只读)。
  • 字符串在内存中的最大大小为 2 GB,或大约 10 亿个字符。
  • String 的本质是一个密封类,不可以被继承,并提供了许多方法。

字符串[x] 字符串指定位置获取

  • 字符串本质是 char 数组
string string2 = "林文韬";
Console.WriteLine(string2[0]);  // 林
  • 字符串可以通过数组的形式访问,类似于索引器。可以通过查看 string 类源码,找到 this[int index] 索引器。

ToCharArray方法 字符串转为 char 数组

string string2 = "林文韬";
char[] chars = string2.ToCharArray();
Console.WriteLine(chars[1]);  // 文

// 遍历字符串一次打印字符串中的字符
for (int i = 0; i < string2.Length; i++)
{
    Console.WriteLine(string2[i]);  // 林 文 韬
}

Format方法 字符串拼接

  • 字符串拼接方法 Format
string string3 = string.Format("{0}{1}{2}", 183, 1834, 8848);
Console.WriteLine(string3);  // 18318348848
  • Format 方法有多个重载。

IndexOf方法 正向查找字符位置

  • 正向查找字符位置方法 IndexOf
string string4 = "我是林文韬";
int index = string4.IndexOf("林");
Console.WriteLine(index);  // 2

index = string4.IndexOf("文韬");
Console.WriteLine(index);  // 3,多个字符会返回匹配的第一个字符的索引

// 没找到字符,默认返回 -1
index = string4.IndexOf("吊");
Console.WriteLine(index);  // -1

LastIndexOf方法 反向查找指定字符串位置

  • 反向查找指定字符串位置方法 LastIndexOf
string string5 = "我是林文韬林文韬";
// 匹配到对应字符后,返回最后出现在这个字符串的字符的首个字符的索引
index = string5.LastIndexOf("林文韬");
Console.WriteLine(index);  // 5

// 没找到字符,默认返回 -1
index = string5.LastIndexOf("林天霸");
Console.WriteLine(index);  // -1

Remove方法 移除指定位置后的字符

  • 移除指定位置后的字符方法 Remove 有两个重载
string string6 = "我是林文韬林文韬";
// 移除,参数1为开始位置后的所有字符
string6.Remove(4);  // 不会改变原字符串,会返回新的字符串
Console.WriteLine(string6);  // 我是林文韬林文韬

// 重新赋值可以得到,移除指定位置后的字符后返回的字符
string6 = string6.Remove(4);
Console.WriteLine(string6);  // 我是林文

// 移除,参数1为开始位置,参数2为字符个数的对应字符
// 现在 string6 的值是 "我是林文",移除开始位置为1后的两个字符,结果为 "我文"
string6 = string6.Remove(1, 2);
Console.WriteLine(string6);  // 我文

Replace方法 替换指定字符串

  • 替换指定字符串方法 Replace。执行了替换指定字符串方法后,原字符串的值不会改变,会返回新的字符串。
string string7 = "我是林文韬林文韬";
string7.Replace("林文韬", "老炮儿");  // 不会改变原字符串,会返回新的字符串
Console.WriteLine(string7);  // 我是林文韬林文韬

// 重新赋值可以得到,替换指定字符串后返回的字符
string7 = string7.Replace("林文韬", "老炮儿");
Console.WriteLine(string7);  // 我是老炮儿老炮儿

ToUpper方法和ToLower方法 大小写转换

  • 大小写转换方法 ToUpperToLower。执行了大小写转换方法后,原字符串的值不会改变,会返回新的字符串。
string string8 = "linwentaozhendeshuai";
string8.ToUpper();  // 不会改变原字符串,会返回新的字符串
Console.WriteLine(string8);  // linwentaozhendeshuai

// 重新赋值可以得到,转大写后返回的字符
string8 = string8.ToUpper();
Console.WriteLine(string8);  // LINWENTAOZHENDESHUAI

string8.ToLower();  // 不会改变原字符串,会返回新的字符串
Console.WriteLine(string8);  // LINWENTAOZHENDESHUAI

// 重新赋值可以得到,转小写后返回的字符
string8 = string8.ToLower();
Console.WriteLine(string8);  // linwentaozhendeshuai

Substring方法 字符串截取

  • 字符串截取方法 Substring 有两个重载。执行了字符串截取方法后,原字符串的值不会改变,会返回新的字符串。
string string9 = "林文韬林文韬";
// 截取,参数1为开始位置后的所有字符
string9.Substring(2);  // 不会改变原字符串,会返回新的字符串
Console.WriteLine(string9); 

 // 林文韬林文韬

// 重新赋值可以得到,截取指定位置后的字符后返回的字符
string9 = string9.Substring(2);
Console.WriteLine(string9);  // 韬林文韬

// 截取,参数1为开始位置,参数2为字符个数的对应字符
// 不会自动的帮助你判断是否越界,你需要自己去判断
// string9 = string9.Substring(2, 3);//报错
// 现在 string9 的值是 "韬林文韬",索引2(含)的字符后只有两个字符 "文韬" 了,截取不了三个
// 现在 string9 的值是 "韬林文韬",截取开始位置为2后的两个字符,结果为 "文韬" 
string9 = string9.Substring(2, 2);
Console.WriteLine(string9);  // 文韬

Split方法 字符串切割

  • 字符串切割方法 Split
// 可能运用到策划配的配置表中
string string10 = "1_1|2_2|3_3|5_1|6_1|7_2|8_3";

// 一般切割完拿一个 string 数组来装
string[] stringArray = string10.Split('|');

for (int i = 0; i < stringArray.Length; i++)
{
    Console.WriteLine(stringArray[i]);
}
// 1_1
// 2_2
// 3_3
// 5_1
// 6_1
// 7_2
// 8_3

25.2 知识点代码

using System;

namespace Lesson23_面向对象相关_string
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("string");

            #region 知识点一 string字符串类概述

            //String是string类的别名 两个都可以用 类似Object和object
            string string1 = "string1";
            String String1 = "String1";

            //字符串是用于表示文本的字符的顺序集合。
            //对象 String 是表示字符串的 System.Char 对象的连续集合; System.Char 对象对应于 UTF - 16 代码单元。
            //对象的值 String 是对象的顺序集合 System.Char 的内容,该值是不可变的, (也就是说,它是只读) 。
            //有关字符串不可变性的详细信息,请参阅 不可变性和 StringBuilder 类 部分。
            //内存中对象的最大大小 String 为 2 - GB,或大约 10 亿个字符。
            //点进去看String的本质 本质是一个密封类 不可以被继承 提供了很多的方法

            #endregion

            #region 知识点二 字符串指定位置获取

            //字符串本质是char数组
            string string2 = "林文韬";
            Console.WriteLine(string2[0]);//林
            //看到能通过一个类的实例能通过数组的形式访问 要联想到索引器
            //可以进去string类源码查看 搜索this 看到string的索引器如下:
            //
            // 摘要:
            //     Gets the System.Char object at a specified position in the current System.String
            //     object.
            //
            // 参数:
            //   index:
            //     A position in the current string.
            //
            // 返回结果:
            //     The object at position index.
            //
            // 异常:
            //   T:System.IndexOutOfRangeException:
            //     index is greater than or equal to the length of this object or less than zero.
            //public char this[int index] { get; }


            //字符串转为char数组
            //可以通过string类里的ToCharArray方法把string转为一个char数组
            char[] chars = string2.ToCharArray();
            Console.WriteLine(chars[1]);//文

            //可以遍历字符串一次打印字符串中的字符
            for (int i = 0; i < string2.Length; i++)
            {
                Console.WriteLine(string2[i]);//林 文 韬
            }

            #endregion

            #region 知识点三 字符串拼接

            //字符串拼接方法Format
            string string3 = string.Format("{0}{1}{2}", 183, 1834,8848);
            Console.WriteLine(string3);//183 183 48848

            //Format方法也有很多重载

            #endregion

            #region 知识点四 正向查找字符位置

            //正向查找字符位置方法IndexOf

            string string4 = "我是林文韬";
            //                0 1 2 3 4

            int index = string4.IndexOf("林");
            Console.WriteLine(index);//2

            index = string4.IndexOf("文韬");
            Console.WriteLine(index);//3 多个字符会返回匹配的第一个字符的索引

            //没找到字符 默认返回-1
            index = string4.IndexOf("吊");
            Console.WriteLine(index);//-1

            #endregion

            #region 知识点五 反向查找指定字符串位置

            //反向查找指定字符串位置方法LastIndexOf

            string string5 = "我是林文韬林文韬";
            //                0 1 2 3 4 5 6 7

            //匹配到对应字符后 返回最后出现在这个字符串的字符的首个字符的索引
            index = string5.LastIndexOf("林文韬");
            Console.WriteLine(index);//5

            //没找到字符 默认返回-1
            index = string5.LastIndexOf("林天霸");
            Console.WriteLine(index);//-1

            #endregion

            #region 知识点六 移除指定位置后的字符

            //移除指定位置后的字符方法Remove 有两个重载
            //注意!!执行了移除方法后原字符串的值不会改变 会返回新的字符串

            string string6 = "我是林文韬林文韬";
            //                0 1 2 3 4 5 6 7

            //移除 参数1为开始位置 后的所有字符

            string6.Remove(4);//不会改变原字符串 会返回新的字符串
            Console.WriteLine(string6);//我是林文韬林文韬

            //重新赋值可以得到 移除指定位置后的字符 后 返回的字符
            string6 = string6.Remove(4);
            Console.WriteLine(string6);//我是林文

            //移除 参数1为开始位置 参数2为字符个数 的对应字符

            //现在string6的值是 我是林文 移除开始位置为1后的两个字符 结果为 我文 
            string6 = string6.Remove(1, 2);
            Console.WriteLine(string6);//我文

            #endregion

            #region 知识点七 替换指定字符串

            //替换指定字符串方法Replace
            //注意!!执行了替换指定字符串方法后原字符串的值不会改变 会返回新的字符串


            string string7 = "我是林文韬林文韬";
            //                0 1 2 3 4 5 6 7

            string7.Replace("林文韬", "老炮儿");//不会改变原字符串 会返回新的字符串
            Console.WriteLine(string7);//我是林文韬林文韬

            //重新赋值可以得到  替换指定字符串 后 返回的字符
            string7 = string7.Replace("林文韬", "老炮儿");
            Console.WriteLine(string7);//我是老炮儿老炮儿

            #endregion

            #region 知识点八 大小写转换

            //大小写转换方法ToUpper ToLower
            //注意!!执行了大小写转换方法后原字符串的值不会改变 会返回新的字符串

            string string8 = "linwentaozhendeshuai";

            string8.ToUpper();//不会改变原字符串 会返回新的字符串
            Console.WriteLine(string8);//linwentaozhendeshuai

            //重新赋值可以得到  转大写 后 返回的字符
            string8 = string8.ToUpper();
            Console.WriteLine(string8);//LINWENTAOZHENDESHUAI

            string8.ToLower();//不会改变原字符串 会返回新的字符串
            Console.WriteLine(string8);//LINWENTAOZHENDESHUAI

            //重新赋值可以得到  转小写 后 返回的字符
            string8 = string8.ToLower();
            Console.WriteLine(string8);//linwentaozhendeshuai

            #endregion

            #region 知识点九 字符串截取

            //字符串截取方法Substring 有两个重载
            //注意!!执行了字符串截取方法后原字符串的值不会改变 会返回新的字符串

            string string9 = "林文韬林文韬";
            //                0 1 2 3 4 5 

            //截取 参数1为开始位置 后的所有字符
            string9.Substring(2);//不会改变原字符串 会返回新的字符串
            Console.WriteLine(string9);//林文韬林文韬

            //重新赋值可以得到 截取指定位置后的字符 后 返回的字符
            string9 = string9.Substring(2);
            Console.WriteLine(string9);//韬林文韬

            //截取 参数1为开始位置 参数2为字符个数 的对应字符

            //不会自动的帮助你判断是否越界 你需要自己去判断
            //string9 = string9.Substring(2, 3);//报错
            //现在string9的值是 韬林文韬 索引2(含)的字符后只有两个字符 文韬 了 截取不了三个

            //现在string9的值是 韬林文韬 截取开始位置为2后的两个字符 结果为 文韬 
            string9 = string9.Substring(2, 2);
            Console.WriteLine(string9);//文韬

            #endregion

            #region 知识点十 字符串切割

            //字符串切割方法Split 

            //可能运用到策划配的配置表中
            string string10 = "1_1|2_2|3_3|5_1|6_1|7_2|8_3";

            //一般切割完拿一个string数组来装
            string[] stringArray = string10.Split('|');

            for (int i = 0; i < stringArray.Length; i++)
            {
                Console.WriteLine(stringArray[i]);
            }
            //1_1
            //2_2
            //3_3
            //5_1
            //6_1
            //7_2
            //8_3

            #endregion
        }
    }
}

25.3 练习题

请写出string中提供的截取和替换对应的函数名

string string1 = "林文韬林文韬";

// 截取字符串
string1 = string1.Substring(1);
Console.WriteLine(string1);//文韬林文韬

// 继续截取字符串
string1 = string1.Substring(1, 1);
Console.WriteLine(string1);//韬

string1 = "林文韬林文韬";

// 替换字符串
string1 = string1.Replace("林文韬", "哈哈哈");
Console.WriteLine(string1);//哈哈哈哈哈哈

请将字符串1|2|3|4|5|6|7变为2|3|4|5|6|7|8,并输出

string string2 = "1 | 2 | 3 | 4 | 5 | 6 | 7";

string[] stringArray = string2.Split('|');//字符串切割 用字符串数组装
string2 = "";

// 遍历字符串数组
for (int i = 0; i < stringArray.Length; i++)
{
    // 转换成整型后 + 1
    string2 += (int.Parse(stringArray[i]) + 1);

    // 不是最后的一个字符串就拼接上|
    if (i != stringArray.Length - 1)
    {
        string2 += "|";
    }
}

Console.WriteLine(string2);//2|3|4|5|6|7|8

String和string、Int32和int、Int16和short、Int64和long他们的区别是什么?

  • string: 别名为 System.String,是 .NET 中字符串类型。
  • int: 别名为 System.Int32,是 .NET 中 32 位有符号整数类型。
  • short: 别名为 System.Int16,是 .NET 中 16 位有符号整数类型。
  • long: 别名为 System.Int64,是 .NET 中 64 位有符号整数类型。

它们的别名和对应的完整类型是等价的,只是为了编码方便,所以在 C# 中可以使用这些别名。

string的频繁修改或者赋值会比较消耗内存空间,产生很多垃圾,加速GC的触发,以下代码分配了多少个新的堆空间?

// string 只要重新赋值不为空都会在堆中分配一个堆空间
string str = null; // 分配一个栈空间,没有分配堆空间
str = "123"; // 堆空间分配了123,第一个新的堆空间
string str2 = str; // 分配一个栈空间,没有分配堆空间,指向上一句中123在堆空间的地址,和 str 值相同
str2 = "321"; // 堆空间分配了321,第二个新的堆空间
str2 += "123"; // 堆空间分配了321123,第三个新的堆空间

// string 的频繁修改或者赋值会比较消耗内存空间,产生很多垃圾,加速 GC 的触发

编写一个函数,将输入的字符串反转。不要使用中间商,你必须原地修改输入数组。交换过程中不使用额外空间

Console.WriteLine("请输入内容");
string string5 = Console.ReadLine();//林文韬真帅

// 直接使用 string 自带的索引器的话会有问题
// 因为 string 的索引器只能 get,不能 set 
// 所以转成 char 数组,再遍历
char[] charArray = string5.ToCharArray();//转成 char 数组

// 遍历 char 数组
for (int i = 0; i < charArray.Length / 2; i++)
{
    // 交换逻辑
    charArray[i] = (char)(charArray[i] + charArray[charArray.Length - 1 - i]);
    charArray[charArray.Length - 1 - i] = (char)(charArray[i] - charArray[charArray.Length - 1 - i]);
    charArray[i] = (char)(charArray[i] - charArray[charArray.Length - 1 - i]);
}

// 遍历输出 char 数组
for (int i = 0; i < charArray.Length; i++)
{
    Console.Write(charArray[i]);
}

// 可以传字符数组,string 构造函数重载 new 出字符串,其实就是 char 数组全部拼接的结果
string5 = new string(charArray);
Console.WriteLine(string5);//帅真韬文林

25.4 练习题代码

using System;

namespace Lesson23_练习题
{
    
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("string练习题");

            #region 练习题一
            //请写出string中提供的截取和替换对应的函数名

            string string1 = "林文韬林文韬";

            string1 = string1.Substring(1);
            Console.WriteLine(string1);//文韬林文韬

            //string1现在的值是 文韬林文韬
            string1 = string1.Substring(1, 1);
            Console.WriteLine(string1);//韬

            string1 = "林文韬林文韬";

            string1 = string1.Replace("林文韬", "哈哈哈");
            Console.WriteLine(string1);//哈哈哈哈哈哈

            #endregion

            #region 练习题二
            //请将字符串1 | 2 | 3 | 4 | 5 | 6 | 7
            //变为     2 | 3 | 4 | 5 | 6 | 7 | 8
            //并输出
            //(使用字符串切割的方法)

            string string2 = "1 | 2 | 3 | 4 | 5 | 6 | 7";

            string[] stringArray = string2.Split('|');//字符串切割 用字符串数组装

            string2 = "";

            //遍历字符串数组
            for (int i = 0; i < stringArray.Length; i++)
            {
                //转换成整型后+1
                string2 += int.Parse(stringArray[i]) + 1;

                //不是最后的一个字符串就拼接上|
                if (i != stringArray.Length - 1)
                {
                    string2 += "|";
                }

            }

            Console.WriteLine(string2);//2|3|4|5|6|7|8

            #endregion

            #region 练习题三
            //String和string、Int32和int、Int16和short、Int64和long他们的区别是什么?

            //他们其实是一样的 只是后者是前者的别名
            //这样做是为了节省代码量 并且和其他编程语言保持一致
            //string 其实就是String类
            //int 其实就是Int32结构体
            //short 其实就是Int16结构体
            //long 其实就是Int64结构体
            #endregion

            #region 练习题四

            //string str = null;
            //str = "123";
            //string str2 = str;
            //str2 = "321";
            //str2 += "123";
            //请问,上面这段代码,分配了多少个新的堆空间

            //string只要重新赋值不为空 都会在堆中分配一个堆空间
            string str = null;//分配一个栈空间 没有分配堆空间
            str = "123";//堆空间分配了123 第一个新的堆空间
            string str2 = str;//分配一个栈空间 没有分配堆空间 指向上一句中123在堆空间的地址 和 str值相同
            str2 = "321";//堆空间分配了321 第二个新的堆空间
            str2 += "123";//堆空间分配了321123 第三个新的堆空间
            //string的频繁修改或者赋值会比较消耗内存空间 产生很多垃圾 加速GC的触发

            #endregion

            #region 练习题五
            //编写一个函数,将输入的字符串反转。不要使用中间商,你必须原地修改输入数组。交换过程中不使用额外空间
            //比如:输入{‘h’,‘e’,‘l’,‘l’,‘o’}
            //输出      {‘o’,‘l’,‘l’,‘e’,‘h’}

            Console.WriteLine("请输入内容");
            string string5 = Console.ReadLine();//林文韬真帅

            //直接使用string自带的索引器的话 会有问题
            //因为string的索引器只能get 不能set 
            //所以转成char数组 再遍历
            char[] charArray = string5.ToCharArray();//转成char数组

            //遍历char数组
            for (int i = 0; i < charArray.Length / 2; i++)
            {
                //交换逻辑

                //这是常规中间商交换做法 但是这道题不能使用额外空间
                //char temp = charArray[i];
                //charArray[i] = charArray[charArray.Length - 1 - i];
                //charArray[charArray.Length - 1 - i] = temp;

                //运用char和int可以相互转换的知识进行处理

                //charArray[i] + charArray[charArray.Length - 1 - i] 加出来是int类型 强转成char 存进charArray[i]中
                //charArray[i]用来暂时存放要交换的两个数相加的和的值
                charArray[i] = (char)(charArray[i] + charArray[charArray.Length - 1 - i]);
                //10 = 1 + 9

                //charArray[i] - charArray[charArray.Length - 1 - i] 减出来是int类型 强转成char 存进charArray[charArray.Length - 1 - i]中
                //因为charArray[i]是用来暂时存放要交换的两个数相加的和的值
                //所以用charArray[i] - charArray[charArray.Length - 1 - i] 得到的其实是原先要交换的两个数未相加前 charArray[i]的值 存进charArray[charArray.Length - 1 - i]中 形成交换
                charArray[charArray.Length - 1 - i] = (char)(charArray[i] - charArray[charArray.Length - 1 - i]);
                //1 = 10 - 9

                //charArray[i] - charArray[charArray.Length - 1 - i] 减出来是int类型 强转成char 存进charArray[i]中
                //因为charArray[i]是用来暂时存放要交换的两个数相加的和的值
                //现在charArray[charArray.Length - 1 - i]的值是 要交换的两个数未相加前 charArray[i]的值
                //所以charArray[i] - charArray[charArray.Length - 1 - i] 得到的其实是原先要交换的两个数未相加前 charArray[charArray.Length - 1 - i的值 存进charArray[i]中 形成交换
                charArray[i] = (char)(charArray[i] - charArray[charArray.Length - 1 - i]);
                //9 = 10 - 1
            }

            //遍历输出char数组
            for (int i = 0; i < charArray.Length; i++)
            {
                Console.Write(charArray[i]);
            }
            //帅真韬文林

            Console.WriteLine();

            //可以传字符数组 string构造函数重载 new出字符串 其实就是char数组全部拼接的结果
            string5 = new string(charArray);
            Console.WriteLine(string5);//帅真韬文林

            #endregion
        }
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏