一、String类概述
在Java中,String类是专门用于处理字符串的引用数据类型。与C语言中通过字符数组或指针处理字符串不同,Java将字符串封装成对象,并提供了丰富的方法来操作字符串,这体现了面向对象的设计思想。
java
// Java中的String类使用示例
public class StringIntroduction {
public static void main(String[] args) {
// 与C语言字符数组的对比
char[] cStr = {'H', 'e', 'l', 'l', 'o'}; // C风格
String javaStr = "Hello"; // Java风格
System.out.println("C风格字符串长度: " + cStr.length);
System.out.println("Java字符串长度: " + javaStr.length());
}
}
二、String对象的创建方式
2.1 三种常用构造方法
java
public class StringConstruction {
public static void main(String[] args) {
// 1. 直接赋值(字面量方式)
String name1 = "小明";
// 2. 使用new关键字创建对象
String name2 = new String("小华");
// 3. 通过字符数组创建
char[] charArray = {'1', '2', '3', '4'};
String name3 = new String(charArray);
// 4. 其他构造方法
byte[] byteArray = {65, 66, 67, 68}; // ASCII码
String name4 = new String(byteArray);
System.out.println("name1: " + name1);
System.out.println("name2: " + name2);
System.out.println("name3: " + name3);
System.out.println("name4: " + name4);
}
}
2.2 内存模型分析
java
public class StringMemoryModel {
public static void main(String[] args) {
// 字符串常量池概念
String s1 = "Java"; // 在常量池中创建
String s2 = "Java"; // 引用常量池中的同一对象
String s3 = new String("Java"); // 在堆中创建新对象
String s4 = new String("Java"); // 在堆中创建另一个对象
System.out.println("s1 == s2: " + (s1 == s2)); // true,同一常量
System.out.println("s1 == s3: " + (s1 == s3)); // false,不同对象
System.out.println("s3 == s4: " + (s3 == s4)); // false,不同对象
System.out.println("s1.equals(s3): " + s1.equals(s3)); // true,内容相同
}
}
内存结构示意图:
text
栈内存: 堆内存: 字符串常量池:
s1 ──────→ 对象1 ←─── "Java"
s2 ──────┘
s3 ──────→ 对象2
s4 ──────→ 对象3
三、字符串比较操作
3.1 比较方法详解
java
public class StringComparison {
public static void main(String[] args) {
// 创建测试字符串
String str1 = new String("Hello");
String str2 = new String("Hello");
String str3 = new String("hello");
String str4 = "Hello";
String str5 = "Hello";
// == 操作符比较(比较引用地址)
System.out.println("== 操作符比较:");
System.out.println("str1 == str2: " + (str1 == str2)); // false
System.out.println("str4 == str5: " + (str4 == str5)); // true
// equals方法比较(比较内容)
System.out.println("\nequals方法比较:");
System.out.println("str1.equals(str2): " + str1.equals(str2)); // true
System.out.println("str1.equals(str3): " + str1.equals(str3)); // false
// equalsIgnoreCase方法(忽略大小写)
System.out.println("\nequalsIgnoreCase方法比较:");
System.out.println("str1.equalsIgnoreCase(str3): " +
str1.equalsIgnoreCase(str3)); // true
// compareTo方法(字典序比较)
System.out.println("\ncompareTo方法比较:");
System.out.println(""abc".compareTo("abd"): " +
"abc".compareTo("abd")); // -1
System.out.println(""abc".compareTo("abC"): " +
"abc".compareTo("abC")); // 32
System.out.println(""abc".compareToIgnoreCase("abC"): " +
"abc".compareToIgnoreCase("abC")); // 0
}
}
四、字符串查找操作
4.1 字符和子串查找
java
public class StringSearch {
public static void main(String[] args) {
String text = "Hello World, Welcome to Java Programming";
// charAt方法 - 获取指定位置字符
System.out.println("charAt方法演示:");
System.out.println("位置0的字符: " + text.charAt(0));
System.out.println("位置6的字符: " + text.charAt(6));
// 遍历所有字符
System.out.println("\n遍历字符串:");
for (int i = 0; i < text.length(); i++) {
System.out.print(text.charAt(i) + " ");
}
System.out.println();
// indexOf方法 - 查找字符或子串位置
System.out.println("\nindexOf方法演示:");
System.out.println("第一次出现'o'的位置: " + text.indexOf('o'));
System.out.println("从位置5开始第一次出现'o'的位置: " + text.indexOf('o', 5));
System.out.println("第一次出现"World"的位置: " + text.indexOf("World"));
System.out.println("第一次出现"Java"的位置: " + text.indexOf("Java"));
// lastIndexOf方法 - 从后往前查找
System.out.println("\nlastIndexOf方法演示:");
System.out.println("最后一次出现'o'的位置: " + text.lastIndexOf('o'));
System.out.println("从位置20开始往前找'o'的位置: " + text.lastIndexOf('o', 20));
System.out.println("最后一次出现"o"的位置: " + text.lastIndexOf("o"));
// contains方法 - 检查是否包含子串
System.out.println("\ncontains方法演示:");
System.out.println("是否包含"Java": " + text.contains("Java"));
System.out.println("是否包含"Python": " + text.contains("Python"));
// startsWith和endsWith方法
System.out.println("\nstartsWith/endsWith方法演示:");
System.out.println("是否以"Hello"开头: " + text.startsWith("Hello"));
System.out.println("是否以"Programming"结尾: " + text.endsWith("Programming"));
}
}
五、字符串转换操作
5.1 类型转换详解
java
public class StringConversion {
public static void main(String[] args) {
// 其他类型转字符串
System.out.println("其他类型转字符串:");
int num = 1234;
double decimal = 12.34;
boolean flag = true;
String str1 = String.valueOf(num);
String str2 = String.valueOf(decimal);
String str3 = String.valueOf(flag);
System.out.println("整数转字符串: " + str1);
System.out.println("小数转字符串: " + str2);
System.out.println("布尔值转字符串: " + str3);
// 验证确实是字符串
System.out.println("\n字符串拼接验证:");
System.out.println(str1 + 11); // "123411" 不是 1245
// 字符串转其他类型
System.out.println("\n字符串转其他类型:");
int parsedInt = Integer.parseInt("1234");
double parsedDouble = Double.parseDouble("12.34");
boolean parsedBoolean = Boolean.parseBoolean("false");
System.out.println("字符串转整数: " + (parsedInt + 11)); // 1245
System.out.println("字符串转小数: " + parsedDouble);
System.out.println("字符串转布尔: " + parsedBoolean);
// 字符数组与字符串互转
System.out.println("\n字符数组与字符串互转:");
String original = "Hello World";
char[] charArray = original.toCharArray();
System.out.print("字符数组: ");
for (char c : charArray) {
System.out.print(c + " ");
}
System.out.println();
String restored = new String(charArray);
System.out.println("恢复的字符串: " + restored);
// 格式化字符串
System.out.println("\n格式化字符串:");
String formatted = String.format("姓名: %s, 年龄: %d, 分数: %.2f",
"张三", 20, 95.5);
System.out.println(formatted);
// 自定义对象转字符串
System.out.println("\n自定义对象转字符串:");
Student student = new Student("李四", 22);
String studentStr = String.valueOf(student);
System.out.println("学生信息: " + studentStr);
}
}
class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{name='" + name + "', age=" + age + "}";
}
}
六、字符串修改操作
6.1 替换操作
java
public class StringModification {
public static void main(String[] args) {
String text = "Hollow Horld, Welcome to Jova Programming";
System.out.println("原始字符串: " + text);
// 单个字符替换
System.out.println("替换'H'为'W': " + text.replace('H', 'W'));
// 字符串替换
System.out.println("替换"Hollow"为"Hello": " +
text.replace("Hollow", "Hello"));
// 替换所有匹配
System.out.println("替换所有'o'为'0': " + text.replaceAll("o", "0"));
// 使用正则表达式替换
System.out.println("替换第一个'o'为'*': " + text.replaceFirst("o", "*"));
// 正则表达式复杂替换
String text2 = "价格: $100, $200, $300";
System.out.println("替换美元符号: " + text2.replaceAll("\$", "¥"));
}
}
6.2 拆分操作
java
public class StringSplit {
public static void main(String[] args) {
// 基本拆分
String data = "student&0x123456&admin&0x789abc";
String[] parts = data.split("&");
System.out.println("基本拆分结果:");
for (int i = 0; i < parts.length; i++) {
System.out.println("部分" + (i + 1) + ": " + parts[i]);
}
// 限制拆分次数
String[] limitedParts = data.split("&", 2);
System.out.println("\n限制拆分次数结果:");
for (String part : limitedParts) {
System.out.println(part);
}
// 特殊字符拆分(需要转义)
String ip = "192.168.1.1";
String[] ipParts = ip.split("\.");
System.out.println("\nIP地址拆分:");
for (String part : ipParts) {
System.out.println(part);
}
// 多个分隔符
String complexData = "apple,banana;orange|grape";
String[] fruits = complexData.split("[,;|]");
System.out.println("\n多分隔符拆分:");
for (String fruit : fruits) {
System.out.println(fruit);
}
// CSV文件解析示例
String csvLine = "John,Doe,30,"New York, NY",Engineer";
String[] csvParts = csvLine.split(",(?=(?:[^"]*"[^"]*")*[^"]*$)");
System.out.println("\nCSV解析:");
for (String part : csvParts) {
System.out.println(part.replace(""", ""));
}
}
}
6.3 截取操作
java
public class StringSubstring {
public static void main(String[] args) {
String text = "123425516789";
System.out.println("原始字符串: " + text);
// 从指定位置截取到末尾
String sub1 = text.substring(7);
System.out.println("从位置7截取到末尾: " + sub1);
// 截取指定范围
String sub2 = text.substring(2, 6);
System.out.println("截取位置2到6: " + sub2);
// 实际应用:提取文件名和扩展名
String filePath = "document.pdf";
int dotIndex = filePath.lastIndexOf('.');
String fileName = filePath.substring(0, dotIndex);
String fileExtension = filePath.substring(dotIndex + 1);
System.out.println("\n文件路径解析:");
System.out.println("文件名: " + fileName);
System.out.println("扩展名: " + fileExtension);
// 提取域名
String url = "https://www.example.com/path/to/page";
int start = url.indexOf("://") + 3;
int end = url.indexOf('/', start);
String domain = (end == -1) ? url.substring(start) : url.substring(start, end);
System.out.println("域名: " + domain);
}
}
七、其他常用操作
7.1 字符串工具方法
java
public class StringUtilities {
public static void main(String[] args) {
String text = " Hello World ";
System.out.println("原始字符串: '" + text + "'");
// 大小写转换
System.out.println("转换为大写: '" + text.toUpperCase() + "'");
System.out.println("转换为小写: '" + text.toLowerCase() + "'");
// 去除空白字符
System.out.println("去除首尾空格: '" + text.trim() + "'");
// 判断空字符串
String emptyStr = "";
String nullStr = null;
String spaceStr = " ";
System.out.println("\n空字符串检查:");
System.out.println("emptyStr为空: " + emptyStr.isEmpty());
System.out.println("spaceStr.trim()为空: " + spaceStr.trim().isEmpty());
// System.out.println("nullStr为空: " + nullStr.isEmpty()); // NullPointerException
// 使用安全检查
System.out.println("安全检查 - emptyStr: " + isNullOrEmpty(emptyStr));
System.out.println("安全检查 - nullStr: " + isNullOrEmpty(nullStr));
System.out.println("安全检查 - spaceStr: " + isNullOrEmpty(spaceStr));
System.out.println("安全检查 - text: " + isNullOrEmpty(text));
// 字符串连接
String[] words = {"Java", "Python", "C++", "JavaScript"};
String joined = String.join(" | ", words);
System.out.println("\n字符串连接: " + joined);
}
// 安全的空字符串检查方法
public static boolean isNullOrEmpty(String str) {
return str == null || str.trim().isEmpty();
}
}
八、字符串不可变性与性能优化
8.1 不可变性原理
java
public class StringImmutability {
public static void main(String[] args) {
// 展示字符串不可变性
String str1 = "Hello";
String str2 = str1; // str2指向同一对象
System.out.println("修改前:");
System.out.println("str1: " + str1 + " | hashCode: " + System.identityHashCode(str1));
System.out.println("str2: " + str2 + " | hashCode: " + System.identityHashCode(str2));
str1 = str1 + " World"; // 创建新对象
System.out.println("\n修改后:");
System.out.println("str1: " + str1 + " | hashCode: " + System.identityHashCode(str1));
System.out.println("str2: " + str2 + " | hashCode: " + System.identityHashCode(str2));
// 性能问题演示
System.out.println("\n字符串拼接性能问题:");
long startTime = System.currentTimeMillis();
String result = "";
for (int i = 0; i < 10000; i++) {
result += i; // 每次循环创建新String对象
}
long endTime = System.currentTimeMillis();
System.out.println("直接拼接耗时: " + (endTime - startTime) + "ms");
}
}
8.2 使用StringBuilder优化
java
public class StringBuilderDemo {
public static void main(String[] args) {
// StringBuilder用于可变字符串操作
System.out.println("StringBuilder性能优化:");
long startTime = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
sb.append(i); // 不会创建新对象
}
String result = sb.toString();
long endTime = System.currentTimeMillis();
System.out.println("StringBuilder拼接耗时: " + (endTime - startTime) + "ms");
// StringBuilder常用方法
StringBuilder builder = new StringBuilder("Hello");
builder.append(" World") // 追加
.insert(5, ",") // 插入
.replace(6, 11, "Java") // 替换
.delete(10, 12); // 删除
System.out.println("最终结果: " + builder.toString());
System.out.println("反转: " + builder.reverse().toString());
}
}
九、最佳实践总结
核心要点
- 字符串创建:优先使用字面量方式,避免不必要的对象创建
- 字符串比较:使用equals()比较内容,==比较引用
- 字符串操作:大量修改时使用StringBuilder
- 内存优化:理解字符串常量池机制
性能建议
java
public class StringBestPractices {
public static void main(String[] args) {
// 1. 使用StringBuilder进行大量拼接
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.append("SELECT * FROM users ")
.append("WHERE age > 18 ")
.append("AND status = 'active' ")
.append("ORDER BY name");
String sql = sqlBuilder.toString();
// 2. 使用equalsIgnoreCase进行不区分大小写比较
String input = "ADMIN";
if ("admin".equalsIgnoreCase(input)) {
System.out.println("权限验证通过");
}
// 3. 使用String.join连接字符串数组
String[] tags = {"java", "programming", "tutorial"};
String tagString = String.join(", ", tags);
System.out.println("标签: " + tagString);
// 4. 使用String.format进行复杂格式化
String message = String.format("用户%s在%s登录,IP地址:%s",
"张三", "2024-01-15", "192.168.1.100");
System.out.println(message);
}
}
String类是Java中最常用且最重要的类之一,深入理解其特性和使用方法对于编写高效的Java程序至关重要。