目录
2. 使用equalsIgnoreCase()方法忽略大小写比较内容
3. 使用compareTo()方法比较字符串大小关系(字典序)
以下是Java和C++中的字符串相关知识:
一、Java中的字符串
1. 定义与创建
• 在Java中,字符串是对象。可以使用双引号直接创建字符串常量,例如:String str = "Hello";
• 也可以使用String类的构造函数创建字符串对象,如String str = new String("Hello");,不过直接使用双引号创建字符串更为常用,因为Java会对相同内容的字符串常量进行优化,使其在内存中只有一份。
2. 字符串操作
(1)连接
• 可以使用+运算符连接字符串。例如:String s1 = "Hello"; String s2 = " World"; String result = s1 + s2;
• 也可以使用StringBuilder或StringBuffer类(在需要频繁连接字符串时效率更高)进行连接操作。例如:
• StringBuilder sb = new StringBuilder();
• sb.append("Hello");
• sb.append(" World");
• String result = sb.toString();
(2)获取长度
• 使用length()方法获取字符串的长度。例如:String str = "Hello"; int len = str.length();
• 索引和切片(Java中称为子串操作)
• 使用charAt()方法获取指定索引处的字符,索引从0开始。例如:String str = "Hello"; char c = str.charAt(1);(这里c的值为'e')
• 使用substring()方法获取子串。有两种重载形式:
• substring(int beginIndex):返回从beginIndex开始到字符串末尾的子串。例如:String str = "Hello"; String sub = str.substring(1);(sub的值为"ello")
• substring(int beginIndex, int endIndex):返回从beginIndex开始到endIndex - 1的子串。例如:String str = "Hello"; String sub = str.substring(1, 3);(sub的值为"el")
(3)查找子串
• 使用indexOf()方法查找子串首次出现的位置,若找到则返回索引值,否则返回 - 1。例如:String str = "Hello World"; int pos = str.indexOf("World");(pos的值为6)
• 还有lastIndexOf()方法用于查找子串最后一次出现的位置。
(4)字符串比较
• 使用equals()方法比较两个字符串的内容是否相等。例如:String s1 = "Hello"; String s2 = new String("Hello"); boolean isEqual = s1.equals(s2);(isEqual的值为true)
• 注意不要使用==来比较字符串内容,==在Java中比较的是对象的引用(内存地址),除非是比较字符串常量(因为Java对相同内容的字符串常量优化为同一对象)。
(5) 字符串转换
• 可以使用getBytes()方法将字符串转换为字节数组(例如在进行网络传输或文件存储时),默认使用平台的字符编码。例如:String str = "Hello"; byte[] bytes = str.getBytes();
• 使用toCharArray()方法将字符串转换为字符数组。例如:String str = "Hello"; char[] charArray = str.toCharArray();
(6)Java中的字符串基本操作拓展
一、创建字符串
1. 直接创建字符串常量
• 使用双引号创建字符串常量是最常见的方式。例如:String str1 = "Hello, World!";这种方式创建的字符串会被存储在字符串池中(如果池中不存在相同内容的字符串)。
2. 使用String类构造函数创建
• 可以从字符数组创建字符串。例如:char[] charArray = {'H', 'e', 'l', 'l', 'o'}; String str2 = new String(charArray);
• 也可以指定字符数组的一部分来创建字符串。例如:char[] charArray = {'H', 'e', 'l', 'l', 'o'}; String str3 = new String(charArray, 1, 3); // 从索引1开始取3个字符,结果为 "ell"
二、获取字符串信息
1. 获取字符串长度
• 使用length()方法。例如:String str = "Hello"; int len = str.length(); // len的值为5
2. 获取指定位置的字符
• 使用charAt()方法。例如:String str = "Hello"; char c = str.charAt(1); // c的值为 'e'
三、字符串比较
1. 使用equals()方法比较内容
• 例如:String s1 = "Hello"; String s2 = new String("Hello"); boolean isEqual = s1.equals(s2); // isEqual为true
2. 使用equalsIgnoreCase()方法忽略大小写比较内容
• 例如:String s1 = "Hello"; String s2 = "hello"; boolean isEqualIgnoreCase = s1.equalsIgnoreCase(s2); // isEqualIgnoreCase为true
3. 使用compareTo()方法比较字符串大小关系(字典序)
• 例如:String s1 = "Apple"; String s2 = "Banana"; int result = s1.compareTo(s2); // result为负数,因为 "Apple" 在字典序中排在 "Banana" 之前
四、字符串查找
1. 查找子串首次出现的位置(indexOf)
• 例如:String str = "Hello, World!"; int pos = str.indexOf("World"); // pos的值为7
• 还可以指定从哪个索引位置开始查找。例如:int pos2 = str.indexOf("o", 5); // 从索引5开始查找字符 'o' 的位置
2. 查找子串最后一次出现的位置(lastIndexOf)
• 例如:String str = "Hello, World, Hello"; int pos = str.lastIndexOf("Hello"); // pos的值为13
五、字符串截取
1. 使用substring方法截取子串(从指定位置到末尾)
• 例如:String str = "Hello, World!"; String sub1 = str.substring(7); // sub1的值为 "World!"
2. 使用substring方法截取指定范围的子串
• 例如:String str = "Hello, World!"; String sub2 = str.substring(0, 5); // sub2的值为 "Hello"
六、字符串替换
1. 使用replace方法替换单个字符
• 例如:String str = "Hello"; String newStr = str.replace('l', 'p'); // newStr的值为 "Heppo"
2. 使用replaceAll方法按照正则表达式替换
• 例如:String str = "Hello123"; String newStr = str.replaceAll("\\d", "X"); // newStr的值为 "HelloXXX",将所有数字替换为 'X'
3. 使用replaceFirst方法替换首次匹配的子串
• 例如:String str = "Hello, World, Hello"; String newStr = str.replaceFirst("Hello", "Hi"); // newStr的值为 "Hi, World, Hello"
3.Java中的字符串拓展
1. 不可变性
• 在Java中,String对象是不可变的。一旦创建,就不能修改其内容。例如:
• String str = "Hello";
• 当执行str = str + " World";时,实际上是创建了一个新的String对象,而原有的"Hello"对象并没有被修改。这一特性使得字符串在多线程环境下使用更加安全,但在频繁修改字符串内容的情况下,可能会导致性能问题(可以使用StringBuilder或StringBuffer来解决)。
2. 字符串格式化
• Java提供了String.format()方法用于格式化字符串,类似于C语言中的printf风格的格式化。例如:
• int num = 10;
• String formatted = String.format("The number is %d", num);
• 支持的格式化符号有%d(整数)、%f(浮点数)、%s(字符串)等,还可以指定格式化的宽度、精度等参数,如String.format("%.2f", 3.14159)会将浮点数格式化为保留两位小数的字符串。
3. 字符串池
• Java为了提高性能和节省内存,维护了一个字符串池。当使用双引号创建字符串常量时,JVM会首先在字符串池中查找是否已经存在相同内容的字符串,如果存在,则直接返回该字符串的引用;如果不存在,则创建一个新的字符串对象并放入字符串池中。例如:
• String s1 = "Hello";
• String s2 = "Hello";
• 这里s1和s2实际上指向字符串池中的同一个对象,可以使用==进行比较(因为它们是同一个对象的引用),并且这种比较方式在比较字符串常量时是有效的,但对于使用new创建的字符串对象则不适用(因为new总是创建一个新的对象实例)。
4. 遍历字符串
• 可以使用for - each循环遍历字符串中的字符。例如:
• String str = "Hello";
• for (char c : str) {
• System.out.println(c);
• }
• 也可以使用传统的for循环结合charAt()方法进行遍历:
• for (int i = 0; i < str.length(); i++) {
• char c = str.charAt(i);
• System.out.println(c);
• }
5. 正则表达式与字符串
• Java中的String类提供了一些与正则表达式相关的方法。例如,matches()方法用于判断字符串是否匹配某个正则表达式模式。
• String str = "12345";
• boolean isNumeric = str.matches("\\d+"); // 判断是否全是数字,这里isNumeric为true
• split()方法可以根据正则表达式来分割字符串。
• String text = "apple,banana,cherry";
• String[] parts = text.split(","); // 按照逗号分割字符串,得到一个包含"apple"、"banana"和"cherry"的数组
• replaceAll()方法使用正则表达式替换字符串中的部分内容。
• String input = "Hello, world!";
• String output = input.replaceAll("world", "Java"); // 将"world"替换为"Java",得到"Hello, Java!"
6. 国际化(i18n)与字符串
• Java通过java.util.ResourceBundle类支持国际化。可以将不同语言版本的字符串存储在资源文件(通常是.properties文件)中。
• 例如,有一个messages.properties文件包含默认语言(如英语)的字符串:greeting=Hello,和一个messages_fr.properties文件包含法语版本的字符串:greeting=Bonjour。
• 在代码中,可以这样使用:
• ResourceBundle bundle = ResourceBundle.getBundle("messages", Locale.getDefault());
• String greeting = bundle.getString("greeting");
7. 空字符串与null的区别
• 在Java中,空字符串""是一个长度为0的有效字符串对象,而null表示没有字符串对象的引用。
• 在处理字符串时需要注意区分这两种情况。例如:
• String str1 = "";
• String str2 = null;
• 当调用str1.length()时会返回0,而调用str2.length()会抛出NullPointerException。
8. 字符串编码转换(高级用法)
• 如果需要在不同的字符编码之间进行转换,可以使用java.nio.charset.Charset类。
• 例如,将UTF - 8编码的字节数组转换为字符串:
• byte[] utf8Bytes = { - 17, - 65, - 67, 72, 101, 108, 108, 111};
• Charset utf8Charset = Charset.forName("UTF - 8");
• String str = new String(utf8Bytes, utf8Charset);
二、C++中的字符串
1. 定义与创建(C++ 中的std::string)
• 在C++中,可以使用std::string类型来处理字符串。需要包含<string>头文件。例如:#include <string>,然后可以创建字符串对象,如std::string str = "Hello";
• 也可以使用构造函数创建空字符串或从字符数组创建字符串,如std::string str1;(创建空字符串),char arr[] = "Hello"; std::string str2(arr);
2. 字符串操作
(1)连接
• 可以使用+运算符连接std::string对象和字符串字面量或其他std::string对象。例如:std::string s1 = "Hello"; std::string s2 = " World"; std::string result = s1 + s2;
• 还可以使用append()方法来连接字符串。例如:std::string s1 = "Hello"; std::string s2 = " World"; s1.append(s2);
(2)获取长度
• 使用length()或size()方法获取字符串的长度。例如:std::string str = "Hello"; int len = str.length();或者int len = str.size();
(3)索引和切片(C++中的子串操作)
• 可以使用[]运算符访问字符串中的单个字符,索引从0开始。例如:std::string str = "Hello"; char c = str[1];(这里c的值为'e')
• 使用substr()方法获取子串。例如:std::string str = "Hello World"; std::string sub = str.substr(6);(sub的值为"World"),也可以指定长度,如std::string sub = str.substr(0, 5);(sub的值为"Hello")
(4)查找子串
• 使用find()方法查找子串首次出现的位置,若找到则返回索引值,否则返回std::string::npos。例如:std::string str = "Hello World"; size_t pos = str.find("World");
(5) 字符串比较
• 可以使用==、!=、<、>、<=、>=等运算符比较std::string对象。例如:std::string s1 = "Hello"; std::string s2 = "Hello"; bool isEqual = s1 == s2;
(5)字符串与字符数组的转换
• 从std::string转换为字符数组:可以使用c_str()方法,它返回一个指向以空字符结尾的C - 风格字符串(字符数组)的指针。例如:std::string str = "Hello"; const char* cstr = str.c_str();
• 从字符数组创建std::string对象如前面所述,可以直接使用构造函数或者赋值操作。例如:char arr[] = "Hello"; std::string str(arr);
(6)C++中的字符串基本操作拓展
一、创建字符串
1. 直接初始化
• 使用std::string类型,直接用字符串常量初始化。例如:std::string str1 = "Hello";
2. 默认初始化
• 例如:std::string str2; 创建一个空字符串。
3. 从字符数组初始化
• 例如:char arr[] = "Hello"; std::string str3(arr);
4. 使用部分字符数组初始化
• 例如:char arr[] = "Hello"; std::string str4(arr, 1, 3); // 从索引1开始取3个字符,结果为 "ell"
二、获取字符串信息
1. 获取字符串长度
• 使用length()或size()方法,它们是等效的。例如:std::string str = "Hello"; size_t len = str.length(); // len的值为5
2. 获取指定位置的字符
• 使用[]运算符。例如:std::string str = "Hello"; char c = str[1]; // c的值为 'e'
三、字符串比较
1. 使用比较运算符(==、!=、<、>、<=、>=)
• 例如:std::string s1 = "Hello"; std::string s2 = "Hello"; bool isEqual = s1 == s2; // isEqual为true
2. 使用compare方法比较字符串大小关系(字典序)
• 例如:std::string s1 = "Apple"; std::string s2 = "Banana"; int result = s1.compare(s2); // result为负数,因为 "Apple" 在字典序中排在 "Banana" 之前
四、字符串查找
1. 查找子串首次出现的位置(find)
• 例如:std::string str = "Hello, World!"; size_t pos = str.find("World"); // pos的值为7
• 还可以指定从哪个索引位置开始查找。例如:size_t pos2 = str.find("o", 5); // 从索引5开始查找字符 'o' 的位置
2. 查找子串最后一次出现的位置(rfind)
• 例如:std::string str = "Hello, World, Hello"; size_t pos = str.rfind("Hello"); // pos的值为13
五、字符串截取
1. 使用substr方法截取子串(从指定位置到末尾)
• 例如:std::string str = "Hello, World!"; std::string sub1 = str.substr(7); // sub1的值为 "World!"
2. 使用substr方法截取指定范围的子串
• 例如:std::string str = "Hello, World!"; std::string sub2 = str.substr(0, 5); // sub2的值为 "Hello"
六、字符串替换
1. 使用replace方法替换单个字符或子串
• 例如:std::string str = "Hello"; str.replace(1, 1, "p"); // 将索引1处的字符替换为 'p',结果为 "Hepo"
• 例如:std::string str = "Hello, World"; str.replace(str.find("World"), 5, "Universe"); // 将 "World" 替换为 "Universe",结果为 "Hello, Universe"
3.C++中的字符串拓展
1. 内存管理
• 与Java不同,C++中的std::string对象需要考虑内存管理。不过,std::string类内部已经对内存进行了有效的管理。当字符串的长度发生变化时(如连接、追加操作),std::string会自动重新分配足够的内存来容纳新的内容。例如:
• std::string str = "Hello";
• str = str + " World";
• 在这个过程中,std::string类会处理内存的重新分配,以确保能够存储新的字符串内容。
2. 字符串的迭代器
• 可以使用迭代器来遍历std::string对象。例如:
• std::string str = "Hello";
• for (std::string::iterator it = str.begin(); it!= str.end(); ++it) {
• std::cout << *it;
• }
• 也可以使用基于范围的for循环(C++11引入),这是一种更简洁的遍历方式:
• std::string str = "Hello";
• for (char c : str) {
• std::cout << c;
• }
3. 字符串与数字的转换
• 字符串转数字
• 对于将字符串转换为整数,可以使用std::stoi(转换为int)、std::stol(转换为long)等函数。例如:
• std::string numStr = "123";
• int num = std::stoi(numStr);
• 对于浮点数,可以使用std::stof(转换为float)、std::stod(转换为double)等函数。
• 数字转字符串
• 可以使用std::to_string函数将数字转换为字符串。例如:
• int num = 123;
• std::string numStr = std::to_string(num);
4. 原始字符串字面量(C++11引入)
• C++11提供了原始字符串字面量的支持,这对于处理包含特殊字符(如反斜杠、双引号等)的字符串非常有用。原始字符串字面量以R"(开始,以)"结束。例如:
• std::string rawStr = R"(This is a "raw" string \ with special characters.)";
• 在这个字符串中,特殊字符不需要进行转义处理,与普通字符串字面量相比,更方便地表示复杂的字符串内容。
5. 字符串的拼接效率优化
• 当使用+运算符多次拼接std::string时,每次拼接都会创建一个新的临时对象,这可能会导致性能问题。为了提高效率,可以使用std::ostringstream。
• 例如:
• #include <sstream>
• std::ostringstream oss;
• oss << "Hello";
• oss << " World";
• std::string result = oss.str();
6. 自定义字符串类(进阶概念)
• 在C++中,可以根据需求自定义字符串类。需要考虑内存管理、字符存储方式(如动态数组)、字符串操作方法(如连接、查找、比较等)的实现。
• 例如,一个简单的自定义字符串类的部分实现:
class MyString {
private:
char* data;
size_t length;
public:
MyString();
MyString(const char* str);
~MyString();
MyString operator+(const MyString& other);
bool operator==(const MyString& other);
// 其他方法定义...
};
7. C++20中的字符串新特性(如果适用)
• C++20引入了一些新的字符串相关特性。例如,std::format函数提供了更强大和类型安全的格式化功能,类似于Python中的格式化字符串。
• int num = 42;
• std::string formatted = std::format("The number is {}", num);
• 它还支持更复杂的格式化选项,如格式化对齐、填充等。
8. 字符串与文件操作
• 在C++中,std::string经常与文件操作结合使用。例如,使用std::ifstream读取文件内容到std::string对象。
#include <iostream>
#include <fstream>
#include <sstream>
int main() {
std::ifstream file("test.txt");
std::stringstream buffer;
buffer << file.rdbuf();
std::string fileContent = buffer.str();
std::cout << fileContent << std::endl;
return 0;
}
• 同样,也可以使用std::ofstream将std::string内容写入文件。