Java 字符串
Java - String 类
Section titled “Java - String 类”在 Java 中,String 是基础且重要的,用于表示字符序列。与原始类型不同,Java 中的 String 是由 java.lang.String 类提供的对象。
本教程将使用现代 Java 实践探索如何创建和操作 String。
创建 String
Section titled “创建 String”最常用且推荐的创建 String 的方法是使用 String 字面量:
// 将引用分配给字符串常量池中现有或新的 String 对象。String greeting = "Hello, world!";当编译器遇到一个 String 字面量时,它会创建一个 String 对象。为了提高效率,Java 维护了一个特殊的内存区域,称为“String Pool”(字符串常量池)。如果常量池中已存在相同的字面量,则会重用现有对象的引用。
你也可以从字符数组创建 String:
public class StringCreationDemo {
public static void main(String[] args) { char[] helloArray = { 'H', 'e', 'l', 'l', 'o', '.' }; String helloString = new String(helloArray); System.out.println(helloString); // 输出: Hello. }}注意:虽然你可以使用 new String(“literal”),但在大多数情况下通常不推荐这样做,因为它会绕过 String Pool,不必要地创建一个新对象。
对于多行 String (Java 15+),使用 Text Blocks 更清晰:
String html = """ <html> <body> <p>Hello, world</p> </body> </html> """;System.out.println(html);理解 String 的不可变性
Section titled “理解 String 的不可变性”Java 中一个重要的概念是 String 对象是 immutable(不可变的)。这意味着一旦创建了 String 对象,其内部状态(字符序列)就不能更改。任何看似修改 String 的方法(如 toUpperCase() 或 substring())实际上都会创建并返回一个包含修改后内容的 new String 对象,而原始 String 则保持不变。
为什么是不可变的?它提供了几个优点:
- **线程安全 (Thread Safety):**不可变对象可以在多个线程之间安全地共享,无需同步。
- 安全性 (Security): String 参数(如文件路径或 URL)在验证后不会意外地被更改。
- **性能 (Performance):**不可变性允许进行优化,例如 String Pool(缓存相同的 String 字面量)。
当你需要对字符序列进行许多修改(例如,在循环内构建一个 String)时,创建大量中间的 String 对象可能会效率低下。对于这些场景,Java 提供了可变类:
- **
StringBuilder:**在单线程环境中进行可变 String 操作的首选。它通常更快。 StringBuffer:StringBuilder的线程安全替代品。只有当你确实需要线程安全时才使用它,因为它会带来性能开销。
使用 StringBuilder 的示例:
StringBuilder builder = new StringBuilder();builder.append("Hello, ");builder.append("world!");builder.append(" The year is ");builder.append(2024);
String result = builder.toString(); // 转换回一个不可变的 String 对象System.out.println(result); // 输出: Hello, world! The year is 2024常用的 String 操作
Section titled “常用的 String 操作”获取 String 长度:
Section titled “获取 String 长度:”length() 方法返回 String 中的字符数。
public class StringLengthDemo {
public static void main(String[] args) { String palindrome = "Dot saw I was Tod"; int len = palindrome.length(); System.out.println("String Length is: " + len); // 输出: String Length is: 17 }}拼接 String:
Section titled “拼接 String:”最常用的拼接 String 的方法是使用 + 运算符。
String firstName = "Ada";String lastName = "Lovelace";String fullName = firstName + " " + lastName; // "Ada Lovelace"System.out.println(fullName);对于简单的情况,+ 运算符很方便。但是,在循环中使用 + 拼接 String 可能会效率低下,因为它可能创建许多中间的 String 对象。在循环中为了更好的性能,请使用 StringBuilder:
String[] words = {"Java", "is", "fun"};StringBuilder sentence = new StringBuilder();for (String word : words) { sentence.append(word).append(" ");}String finalSentence = sentence.toString().trim(); // "Java is fun"System.out.println(finalSentence);String 类也有一个 concat(String str) 方法,但通常更推荐使用 + 运算符和 StringBuilder。
创建格式化 String:
Section titled “创建格式化 String:”静态方法 String.format() 允许创建格式化 String,类似于 C/C++ 中的 printf。
double floatVar = 3.14159;int intVar = 42;String stringVar = "Example";
String fs = String.format("Float: %.2f, Integer: %d, String: %s", floatVar, intVar, stringVar);System.out.println(fs);// 输出: Float: 3.14, Integer: 42, String: Example自 Java 15 起,你还可以使用 formatted() 实例方法,这与 text blocks 配合使用通常很方便:
String name = "World";int year = 2024;String formattedString = """ Hello, %s! Welcome to %d. """.formatted(name, year);System.out.println(formattedString);核心 String 方法
Section titled “核心 String 方法”String 类提供了一套丰富的方法。这里列出了一些最常用的方法,按功能分组:
基本信息与比较:
Section titled “基本信息与比较:”int length(): 返回字符数。示例:“Java”.length() // 4boolean isEmpty(): 如果长度为 0,则返回true。示例:"".isEmpty() // trueboolean isBlank()(Java 11+): 如果 String 为空或只包含空白字符,则返回true。示例:” “.isBlank() // trueboolean equals(Object obj): 比较 String 内容是否相等(区分大小写)。重点:比较 String 内容请使用此方法,不要使用==。boolean equalsIgnoreCase(String anotherString): 比较 String 内容,忽略大小写。int compareTo(String anotherString): 按字典顺序比较 String(如果相等则返回 0,如果当前 String 在前面则返回 <0,如果anotherString在前面则返回 >0)。对于排序很有用。int compareToIgnoreCase(String str): 按字典顺序比较,忽略大小写。
搜索与内容检查:
Section titled “搜索与内容检查:”boolean contains(CharSequence s): 检查 String 是否包含指定的字符序列。示例:“Hello”.contains(“ell”) // trueint indexOf(int ch / String str): 返回第一次出现的索引,如果未找到则返回 -1。可以从指定索引开始搜索:indexOf(…, int fromIndex)。int lastIndexOf(int ch / String str): 返回最后一次出现的索引,如果未找到则返回 -1。可以从指定索引开始向后搜索:lastIndexOf(…, int fromIndex)。boolean startsWith(String prefix): 检查 String 是否以指定前缀开头。示例:“Java”.startsWith(“Ja”) // trueboolean endsWith(String suffix): 检查 String 是否以指定后缀结尾。示例:“Java”.endsWith(“va”) // true
提取子 String 与字符:
Section titled “提取子 String 与字符:”String substring(int beginIndex): 返回从beginIndex到结尾的子 String。String substring(int beginIndex, int endIndex): 返回从beginIndex到endIndex(不包含endIndex)的子 String。示例:“Example”.substring(1, 4) // “xam”char charAt(int index): 返回指定索引处(基于 0)的字符。示例:“Java”.charAt(0) // ‘J’char[] toCharArray(): 将 String 转换为新的字符数组。
操作 (大小写、空白字符、替换):
Section titled “操作 (大小写、空白字符、替换):”String toLowerCase(): 将 String 转换为小写。String toUpperCase(): 将 String 转换为大写。String trim(): 移除开头和结尾的空白字符(基于传统空白字符定义)。String strip()(Java 11+): 移除开头和结尾的空白字符(支持 Unicode)。优于trim()。String stripLeading()/stripTrailing()(Java 11+): 只移除开头或结尾的空白字符。String replace(char oldChar, char newChar): 将所有出现的oldChar替换为newChar。String replace(CharSequence target, CharSequence replacement): 替换所有出现的 target 字符序列。String replaceAll(String regex, String replacement): 替换匹配正则表达式的子 String。String replaceFirst(String regex, String replacement): 替换第一个匹配正则表达式的子 String。String repeat(int count)(Java 11+): 返回将当前 String 重复count次的新 String。
分割与拼接:
Section titled “分割与拼接:”String[] split(String regex): 根据给定的正则表达式匹配项分割 String。示例:“a,b,c”.split(”,”) // {“a”, “b”, “c”}static String join(CharSequence delimiter, CharSequence… elements)(Java 8+): 使用分隔符拼接元素。示例:String.join(”-”, “a”, “b”, “c”) // “a-b-c”static String join(CharSequence delimiter, Iterable<? extends CharSequence> elements)(Java 8+): 使用分隔符拼接集合中的元素。
处理字节 (编码):
Section titled “处理字节 (编码):”byte[] getBytes(Charset charset): 使用指定的字符集将 String 编码为字节序列。**最佳实践:**始终指定Charset,例如StandardCharsets.UTF_8。byte[] getBytes(): 使用平台的默认字符集进行编码。**警告:**避免使用此方法,因为默认字符集在不同系统之间可能变化,导致潜在的 bug。请改用带显式Charset的版本。
此列表涵盖了许多基本方法。有关完整概述和高级方法,请查阅 java.lang.String 类的官方 Java API 文档。