Appearance
13.1 String 基本用法
String 的概念
String 是 Java 中表示字符串的类,用于存储和操作文本数据。在 Java 中,字符串是不可变的,一旦创建就不能修改。
String 的创建方式
1. 使用字符串字面量
java
String str1 = "Hello, Java!";
String str2 = "Hello, Java!"; // 与 str1 引用同一个对象2. 使用 new 关键字
java
String str3 = new String("Hello, Java!");
String str4 = new String("Hello, Java!"); // 与 str3 引用不同的对象3. 使用字符数组
java
char[] charArray = {'H', 'e', 'l', 'l', 'o'};
String str5 = new String(charArray);4. 使用字节数组
java
byte[] byteArray = {72, 101, 108, 108, 111};
String str6 = new String(byteArray);String 的不可变性
String 对象一旦创建,其内容就不能被修改。当我们对字符串进行操作时,实际上是创建了一个新的字符串对象。
示例:
java
public class StringImmutabilityExample {
public static void main(String[] args) {
String str = "Hello";
System.out.println("Original str: " + str);
System.out.println("Original str hashCode: " + str.hashCode());
// 对字符串进行操作,实际上创建了一个新的字符串对象
str = str + " Java";
System.out.println("Modified str: " + str);
System.out.println("Modified str hashCode: " + str.hashCode());
// 再次操作,又创建了一个新的字符串对象
str = str.toUpperCase();
System.out.println("Uppercase str: " + str);
System.out.println("Uppercase str hashCode: " + str.hashCode());
}
}String 池
Java 中的字符串池(String Pool)是存储字符串字面量的特殊区域,位于方法区。当使用字符串字面量创建字符串时,JVM 会先检查字符串池中是否已存在相同内容的字符串,如果存在则直接返回引用,否则创建新的字符串并放入池中。
示例:
java
public class StringPoolExample {
public static void main(String[] args) {
// 使用字符串字面量创建字符串,会放入字符串池
String str1 = "Hello";
String str2 = "Hello";
// 使用 new 关键字创建字符串,不会放入字符串池
String str3 = new String("Hello");
// str1 和 str2 引用同一个对象
System.out.println("str1 == str2: " + (str1 == str2)); // true
// str1 和 str3 引用不同的对象
System.out.println("str1 == str3: " + (str1 == str3)); // false
// 使用 intern() 方法将字符串放入字符串池
String str4 = str3.intern();
System.out.println("str1 == str4: " + (str1 == str4)); // true
}
}String 的常用操作
1. 字符串连接
使用 + 运算符:
java
String str1 = "Hello";
String str2 = "Java";
String result = str1 + " " + str2; // "Hello Java"使用 concat() 方法:
java
String str1 = "Hello";
String str2 = "Java";
String result = str1.concat(" ").concat(str2); // "Hello Java"2. 字符串比较
使用 == 运算符: 比较两个字符串的引用是否相同
java
String str1 = "Hello";
String str2 = "Hello";
String str3 = new String("Hello");
System.out.println(str1 == str2); // true
System.out.println(str1 == str3); // false使用 equals() 方法: 比较两个字符串的内容是否相同
java
String str1 = "Hello";
String str2 = "Hello";
String str3 = new String("Hello");
System.out.println(str1.equals(str2)); // true
System.out.println(str1.equals(str3)); // true使用 equalsIgnoreCase() 方法: 忽略大小写比较两个字符串的内容
java
String str1 = "Hello";
String str2 = "hello";
System.out.println(str1.equals(str2)); // false
System.out.println(str1.equalsIgnoreCase(str2)); // true3. 字符串长度
java
String str = "Hello, Java!";
int length = str.length(); // 124. 字符串索引
java
String str = "Hello";
char firstChar = str.charAt(0); // 'H'
char lastChar = str.charAt(str.length() - 1); // 'o'5. 字符串子串
java
String str = "Hello, Java!";
String subStr1 = str.substring(0, 5); // "Hello"
String subStr2 = str.substring(7); // "Java!"6. 字符串查找
java
String str = "Hello, Java!";
int index1 = str.indexOf('o'); // 4
int index2 = str.lastIndexOf('a'); // 9
int index3 = str.indexOf("Java"); // 7
boolean contains = str.contains("Java"); // true7. 字符串替换
java
String str = "Hello, Java!";
String replaced = str.replace("Java", "World"); // "Hello, World!"8. 字符串分割
java
String str = "apple,banana,orange";
String[] fruits = str.split(","); // ["apple", "banana", "orange"]9. 字符串大小写转换
java
String str = "Hello, Java!";
String upperCase = str.toUpperCase(); // "HELLO, JAVA!"
String lowerCase = str.toLowerCase(); // "hello, java!"10. 字符串 trim
java
String str = " Hello, Java! ";
String trimmed = str.trim(); // "Hello, Java!"String 的常见问题
1. 字符串拼接性能
症状:大量字符串拼接操作导致性能下降
解决方案:对于大量字符串拼接,使用 StringBuilder 或 StringBuffer
示例:
java
// 不推荐:大量字符串拼接
String result = "";
for (int i = 0; i < 1000; i++) {
result += i;
}
// 推荐:使用 StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append(i);
}
String result = sb.toString();2. 字符串空值检查
症状:字符串为空或 null 时导致 NullPointerException
解决方案:使用 equals() 方法时,将常量放在前面,或使用 Objects.equals() 方法
示例:
java
// 不推荐:可能导致 NullPointerException
String str = null;
if (str.equals("Hello")) {
// 代码
}
// 推荐:常量放在前面
if ("Hello".equals(str)) {
// 代码
}
// 推荐:使用 Objects.equals()
if (Objects.equals(str, "Hello")) {
// 代码
}3. 字符串池的使用
症状:创建了大量重复的字符串对象,占用内存
解决方案:使用字符串字面量或 intern() 方法
示例:
java
// 不推荐:每次都创建新对象
String str1 = new String("Hello");
String str2 = new String("Hello");
// 推荐:使用字符串字面量
String str1 = "Hello";
String str2 = "Hello"; // 复用字符串池中的对象
// 推荐:使用 intern() 方法
String str1 = new String("Hello").intern();
String str2 = new String("Hello").intern(); // 复用字符串池中的对象示例:String 基本用法
示例 1:字符串拼接
java
public class StringConcatenationExample {
public static void main(String[] args) {
// 使用 + 运算符
String name = "John";
int age = 30;
String message = "My name is " + name + " and I am " + age + " years old.";
System.out.println(message);
// 使用 concat() 方法
String str1 = "Hello";
String str2 = " ";
String str3 = "World";
String result = str1.concat(str2).concat(str3);
System.out.println(result);
}
}示例 2:字符串比较
java
public class StringComparisonExample {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = "Hello";
String str3 = new String("Hello");
String str4 = "hello";
// 使用 == 运算符
System.out.println("str1 == str2: " + (str1 == str2)); // true
System.out.println("str1 == str3: " + (str1 == str3)); // false
// 使用 equals() 方法
System.out.println("str1.equals(str2): " + str1.equals(str2)); // true
System.out.println("str1.equals(str3): " + str1.equals(str3)); // true
// 使用 equalsIgnoreCase() 方法
System.out.println("str1.equals(str4): " + str1.equals(str4)); // false
System.out.println("str1.equalsIgnoreCase(str4): " + str1.equalsIgnoreCase(str4)); // true
}
}示例 3:字符串操作
java
public class StringOperationsExample {
public static void main(String[] args) {
String str = " Hello, Java World! ";
System.out.println("Original: " + str);
System.out.println("Length: " + str.length());
System.out.println("Trimmed: " + str.trim());
System.out.println("Uppercase: " + str.toUpperCase());
System.out.println("Lowercase: " + str.toLowerCase());
System.out.println("Substring (7, 11): " + str.substring(7, 11));
System.out.println("Index of 'Java': " + str.indexOf("Java"));
System.out.println("Contains 'World': " + str.contains("World"));
System.out.println("Replace 'Java' with 'Python': " + str.replace("Java", "Python"));
// 分割字符串
String fruits = "apple,banana,orange,grape";
String[] fruitArray = fruits.split(",");
System.out.println("Fruits:");
for (String fruit : fruitArray) {
System.out.println("- " + fruit);
}
}
}示例 4:字符串空值检查
java
import java.util.Objects;
public class StringNullCheckExample {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = null;
// 方法 1:使用 == 检查 null
if (str1 != null && str1.equals("Hello")) {
System.out.println("str1 is 'Hello'");
}
// 方法 2:常量放在前面
if ("Hello".equals(str1)) {
System.out.println("str1 is 'Hello'");
}
// 方法 3:使用 Objects.equals()
if (Objects.equals(str1, "Hello")) {
System.out.println("str1 is 'Hello'");
}
// 检查空字符串
String str3 = "";
if (str3.isEmpty()) {
System.out.println("str3 is empty");
}
if (str3.length() == 0) {
System.out.println("str3 is empty");
}
}
}最佳实践
使用字符串字面量:尽量使用字符串字面量创建字符串,避免使用 new 关键字,这样可以利用字符串池提高性能
使用 StringBuilder:对于大量字符串拼接操作,使用 StringBuilder 或 StringBuffer 而不是 + 运算符
常量放在前面:使用 equals() 方法时,将常量放在前面,避免 NullPointerException
使用 Objects.equals():对于可能为 null 的字符串,使用 Objects.equals() 方法进行比较
注意字符串不可变性:记住字符串是不可变的,每次操作都会创建新对象
合理使用 intern():对于需要频繁使用的字符串,可以使用 intern() 方法将其放入字符串池
避免不必要的字符串操作:尽量减少不必要的字符串操作,特别是在循环中
总结
String 是 Java 中表示字符串的类,具有以下特点:
不可变性:String 对象一旦创建,其内容就不能被修改
字符串池:使用字符串字面量创建的字符串会被放入字符串池,提高内存利用率
丰富的方法:提供了大量用于操作字符串的方法,如连接、比较、查找、替换等
常见问题:字符串拼接性能、空值检查、字符串池的使用
通过合理使用 String 类的方法和最佳实践,可以提高代码的性能和可维护性。
