第1课java_字符串String
热度🔥:67 免费课程
授课语音
Java字符串
1. 介绍
Java的字符串String
对象在实际开发中非常广泛地使用。字符串是不可变的、线程安全的,这意味着一旦创建,字符串的内容就不能被修改。如果需要修改字符串(如拼接、替换等),Java会创建一个新的字符串对象,因此不建议频繁修改字符串,以避免性能损失。
比较
字符串的比较包括内容比较和引用比较。在实际开发中,需要根据业务场景做出正确的选择:
- 内容比较:使用
equals()
方法来比较字符串内容是否相同。 - 引用比较:使用
==
运算符来比较两个字符串对象的引用是否相同。
字符串常量池
Java有一个内存优化机制,称为字符串常量池,用于管理字符串字面量。字符串常量池是一个特殊的内存区域,存放字符串的字面量。当创建新的字符串时,JVM会检查常量池,如果池中已经存在该字符串,就直接返回其引用,从而提升性能。
StringBuilder和StringBuffer
这两者都是可变的字符串类:
StringBuilder
是非线程安全的,适合在单线程环境中频繁修改字符串。StringBuffer
是线程安全的,适合在多线程环境中使用。
2. 代码案例
基本操作案例
package com.zhilitech.strings;
import java.util.Arrays;
public class ComprehensiveStringExample {
public static void main(String[] args) {
// 1. 创建字符串
String s1 = "Hello"; // 字符串的字面量,放入字符串常量池
String s2 = new String("World"); // 使用new关键字创建的字符串,不放入常量池
// 2. 字符串长度
int lengthS1 = s1.length(); // 结果是5
System.out.println("Length of s1: " + lengthS1); // 输出: Length of s1: 5
// 3. 获取字符
char firstChar = s1.charAt(0); // 结果是 'H'
System.out.println("First character of s1: " + firstChar); // 输出: First character of s1: H
// 4. 子字符串
String subString = s1.substring(1, 4); // 结果是 "ell"
System.out.println("Substring of s1: " + subString); // 输出: Substring of s1: ell
// 5. 拼接字符串
String concatenated = s1.concat(" ").concat(s2); // 结果是 "Hello World"
System.out.println("Concatenated string: " + concatenated); // 输出: Concatenated string: Hello World
// 6. 字符串比较
// 这里记住不能使用`==`,因为它比较的是对象的引用地址
boolean isEqual = s1.equals("Hello"); // true
boolean isEqualIgnoreCase = s1.equalsIgnoreCase("HELLO"); // true
System.out.println("Is s1 equal to 'Hello': " + isEqual); // 输出: Is s1 equal to 'Hello': true
System.out.println("Is s1 equal to 'HELLO' (ignore case): " + isEqualIgnoreCase); // 输出: Is s1 equal to 'HELLO' (ignore case): true
// 7. 查找子串的位置
int indexOfW = concatenated.indexOf("W"); // 结果是6
System.out.println("Index of 'W': " + indexOfW); // 输出: Index of 'W': 6
// 8. 替换字符串
String replacedString = concatenated.replace("World", "Java"); // 结果是 "Hello Java"
System.out.println("Replaced string: " + replacedString); // 输出: Replaced string: Hello Java
// 9. 转换大小写
String upperCase = s1.toUpperCase(); // 结果是 "HELLO"
String lowerCase = s1.toLowerCase(); // 结果是 "hello"
System.out.println("Uppercase s1: " + upperCase); // 输出: Uppercase s1: HELLO
System.out.println("Lowercase s1: " + lowerCase); // 输出: Lowercase s1: hello
// 10. 去除前后空格
String withSpaces = " Hello World ";
String trimmed = withSpaces.trim(); // 结果是 "Hello World"
System.out.println("Trimmed string: '" + trimmed + "'"); // 输出: Trimmed string: 'Hello World'
// 11. 分割字符串
String[] parts = concatenated.split(" "); // 根据空格分割
System.out.println("Splitted parts:");
for (String part : parts) {
System.out.println(part);
}
// 输出:
// Splitted parts:
// Hello
// World
// 12. 正则表达式替换
String replacedWithRegex = concatenated.replaceAll("\\s", "_"); // 将所有空格替换为下划线
System.out.println("Replaced with regex: " + replacedWithRegex); // 输出: Replaced with regex: Hello_Java
// 13. 字符串池示例
String s3 = "Hello";
String s4 = new String("Hello").intern(); // intern()方法将s4的内容加入字符串池
boolean isSameReference = s1 == s3; // true,s1和s3指向字符串池中的同一个对象
boolean isDifferentReference = s1 == s4; // true,s1和s4也指向字符串池中的同一个对象
System.out.println("s1 and s3 reference equality: " + isSameReference); // 输出: s1 and s3 reference equality: true
System.out.println("s1 and s4 reference equality: " + isDifferentReference); // 输出: s1 and s4 reference equality: true
// 14. 字符串与数组的转换
String[] array = {"Java", "Python", "C++"};
String joined = String.join(", ", array); // 使用逗号和空格连接数组元素
System.out.println("Joined string from array: " + joined); // 输出: Joined string from array: Java, Python, C++
String arrayToString = Arrays.toString(array); // 将数组转换为字符串
System.out.println("Array to string: " + arrayToString); // 输出: Array to string: [Java, Python, C++]
// 15. 格式化字符串
int number = 42;
String formattedString = String.format("The number is %d and the word is %s.", number, s1);
System.out.println("Formatted string: " + formattedString); // 输出: Formatted string: The number is 42 and the word is Hello.
// 16. StringBuilder 示例
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
sb.append("!");
System.out.println("StringBuilder result: " + sb); // 输出: StringBuilder result: Hello World!
// 17. StringBuffer 示例
StringBuffer sbf = new StringBuffer();
sbf.append("Java");
sbf.append(" ");
sbf.append("Programming");
sbf.append("!");
System.out.println("StringBuffer result: " + sbf); // 输出: StringBuffer result: Java Programming!
}
}
常见注意事项案例
package com.zhilitech.strings;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class ComprehensiveStringExample2 {
// 多线程环境的验证
static void runTest(final Appendable appendable) throws InterruptedException {
final int THREAD_COUNT = 10; // 线程数量
final int APPEND_COUNT = 1000; // 每个线程追加的字符数量
Runnable task = () -> {
for (int i = 0; i < APPEND_COUNT; i++) {
try {
appendable.append("X"); // 向appendable对象追加字符
} catch (IOException e) {
// 处理Appendable可能抛出的IOException
e.printStackTrace();
}
}
};
Thread[] threads = new Thread[THREAD_COUNT]; // 创建线程数组
for (int i = 0; i < THREAD_COUNT; i++) {
threads[i] = new Thread(task); // 创建线程任务
threads[i].start(); // 启动线程
}
for (int i = 0; i < THREAD_COUNT; i++) {
threads[i].join(); // 等待所有线程执行完毕
}
System.out.println("Length of result: " + appendable.toString().length()); // 输出结果的长度
}
public static void main(String[] args) throws InterruptedException {
// 1. 字符编码
String originalString = "Hello, 世界!"; // 原始字符串
byte[] utf8Bytes = originalString.getBytes(StandardCharsets.UTF_8); // UTF-8编码
byte[] iso88591Bytes = originalString.getBytes(StandardCharsets.ISO_8859_1); // ISO-
8859-1编码
System.out.println("Original String: " + originalString);
System.out.println("UTF-8 Bytes: " + Arrays.toString(utf8Bytes)); // 输出UTF-8字节数组
System.out.println("ISO-8859-1 Bytes: " + Arrays.toString(iso88591Bytes)); // 输出ISO-8859-1字节数组
// 2. 字符串常量池
String s1 = "Hello"; // 字符串常量池中的字符串
String s2 = "Hello"; // 引用相同的字符串常量
String s3 = new String("Hello"); // 使用new关键字创建的字符串,不在常量池中
String s4 = s3.intern(); // 将s3的内容放入常量池
System.out.println("s1 == s2: " + (s1 == s2)); // true,s1和s2引用相同
System.out.println("s1 == s3: " + (s1 == s3)); // false,s1和s3引用不同
System.out.println("s1 == s4: " + (s1 == s4)); // true,s1和s4引用相同
// 3. 字符串比较陷阱
String a = new String("test"); // 创建新字符串对象
String b = "test"; // 字符串常量池中的字符串
// 注意:虽然内容相同,但对象不同
System.out.println("a == b: " + (a == b)); // false
System.out.println("a.equals(b): " + a.equals(b)); // true,内容相同
// 4. StringBuilder 和 StringBuffer 示例
/*
* StringBuffer 是线程安全的,但由于其方法被同步,性能上不如 StringBuilder。
* StringBuilder 不保证线程安全,适合单线程场景,性能更优。
* 在多线程环境中,StringBuilder 和 StringBuffer 的行为会有所不同。
* StringBuilder 是非线程安全的,而 StringBuffer 是线程安全的,表现会有显著差异。
*/
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
sb.append("!");
System.out.println("StringBuilder result: " + sb); // 输出: StringBuilder result: Hello World!
// 使用 StringBuilder 的多线程环境,线程不安全,输出长度不一致
System.out.println("Using StringBuilder:");
runTest(new StringBuilder());
// 使用 StringBuffer 的多线程环境,线程安全,每次输出都是一致的
System.out.println("\nUsing StringBuffer:");
runTest(new StringBuffer());
// 5. 常见陷阱 - 不正确使用 intern()
String s5 = new String("Interned"); // 创建新字符串对象
String s6 = s5.intern(); // s6 已经在常量池中了
System.out.println("s5 == s6: " + (s5 == s6)); // false,s5 和 s6 不相同
String s7 = "Interned"; // 从常量池中获取字符串
System.out.println("s7 == s6: " + (s7 == s6)); // true,s7 和 s6 相同
}
}
以上就是关于Java字符串的介绍和代码示例,希望能帮助你更好地理解字符串的用法及其特性!