模式切换
字符串
在 Java 中,字符串是一个非常重要的数据类型,用于存储文本信息。Java 提供丰富的字符串操作功能,主要通过 String 类、StringBuilder 类和 StringBuffer 类来实现。
String 类
String 类是 Java 中最常用的字符串类,它是不可变的(immutable),即一旦创建就不能被修改。所有字符串操作都会返回一个新的字符串对象。
声明字符串
在 Java 中可以通过以下方式声明字符串:
java
String str1 = "Hello, World!";
String str2 = new String("Hello, World!");str1是通过字面量生命的,即一个字符串常量,存储在字符串常量池中。str2是通过new关键字创建的,会在堆内存中创建一个新的字符串对象。
注意:
- 在 Java 中,由双引号("")包围的都是字符串,不能作为其他数据类型来使用。如"1+2"的输出不可能是 3。
- 声明字符串变量必须经过初始化才能使用,否则编译器会报出“可能尚未初始化变量”的错误。
创建字符串
Java 中将字符串作为对象来管理,因此可以像创建其他类对象一样来创建字符串对象。创建对象要使用类的构造方法,String 类提供了多种构造方法来创建字符串。
- String(char a[])
用字符数组 a 创建 String 对象。
java
char[] charArray = {'H', 'e', 'l', 'l', 'o'};
String str3 = new String(charArray); // 结果为 "Hello"- String(char a[], int offset, int length)
提取字符数组 a 中从 offset 开始的 length 个字符创建 String 对象。
java
char[] charArray = {'H', 'e', 'l', 'l', 'o'};
String str4 = new String(charArray, 1, 3); // 结果为 "ell"- String(char[] value)
用字符数组 value 创建 String 对象。该构造方法可以分配一个新的 String 对象,使其表示字符数组参数中所有元素连接的结果。
java
char[] charArray = {'H', 'e', 'l', 'l', 'o'};
String str5 = new String(charArray); // 结果为 "Hello"除了上述几种使用 String 类的构造方法来创建字符串变量外,还可以通过字符串常量的引用赋值给一个字符串变量。
java
String str6, str7;
str6 = "Hello"; // 字符串常量赋值
str7 = "Hello"; // 字符串常量赋值
图 内存示意图,str6 与 str 7 引用相同的字符串常量
连接字符串
连接多个字符串
可以使用 + 运算符或 concat() 方法来连接字符串:
java
String str5 = "Hello";
String str6 = "World";
String str7 = str5 + " " + str6; // 使用 + 运算符连接字符串
String str8 = str5.concat(" ").concat(str6); // 使用 concat() 方法连接字符串Java 中一句相连的字符串不能分行书写,需要使用 + 运算符连接,如下:
java
String str = "Hello, "
+ "World!";连接其他数据类型
+ 运算符不仅可以连接字符串,还可以连接其他数据类型(如整数、浮点数等),Java 会自动将其转换为字符串:
java
int num = 123;
String str9 = "The number is " + num; // 结果为 "The number is 123"获取字符串信息
获取字符串长度
使用 length() 方法可以获取字符串的长度:
java
String str10 = "Hello World";
int length = str10.length(); // 长度为 11字符串查找
可以使用 indexOf() 和 lastIndexOf() 方法来查找子字符串或字符的位置。
indexOf()方法返回子字符串或字符第一次出现的位置。lastIndexOf()方法返回子字符串或字符最后一次出现的位置,如果未找到则返回 -1。
java
String str11 = "Hello, World!";
int index1 = str11.indexOf('o'); // 返回第一个 'o' 的位置,结果为 4
int index2 = str11.lastIndexOf('o'); // 返回最后一个 'o' 的位置,结果为 8
int index3 = str11.indexOf("World"); // 返回子字符串 "World" 的起始位置,结果为 7理解字符串的索引位置,需要对下标(索引)概念有所了解。在 Java 中,字符串的索引位置从 0 开始,即第一个字符的索引位置为 0,第二个字符的索引位置为 1,以此类推。

图 字母 o 的索引位置
获取指定索引位置的字符
使用 charAt() 方法可以获取指定索引位置的字符:
java
String str12 = "Hello";
char ch = str12.charAt(1); // 返回索引为 1 的字符,结果为 'e'字符串操作
获取子字符串
使用 substring() 方法可以截取字符串,该方法被两种不同的方法重载:
- substring(int beginIndex):从指定索引开始截取到末尾。
- substring(int beginIndex, int endIndex):从指定索引开始截取到指定索引(不包括)。
java
String str13 = "Hello, World!";
String subStr1 = str13.substring(7); // 从索引 7 开始到末尾,结果为 "World!"
String subStr2 = str13.substring(7, 12); // 从索引 7 开始到索引 12(不包括),结果为 "World"
图 str13.substring(7) 的截取过程
去除空格
使用 trim() 方法可以去除字符串两端的空格:
java
String str14 = " Hello, World! ";
String trimmedStr = str14.trim(); // 结果为 "Hello, World!"字符串替换
使用 replace() 方法可以替换字符串中的字符或子字符串:
- replace(char oldChar, char newChar):将字符串中的 oldChar 替换为 newChar。如果字符串中有多个 oldChar,则全部替换。区分大小写。
java
String str15 = "Hello, World!";
String replacedStr1 = str15.replace('o', 'a'); // 结果为 "Hella, Warld!"
String replacedStr2 = str15.replace("World", "Java"); // 结果为 "Hello, Java!"判断字符串的开始和结束
使用 startsWith() 和 endsWith() 方法可以判断字符串是否以指定的前缀或后缀开始或结束:
java
String str16 = "Hello, World!";
boolean startsWithHello = str16.startsWith("Hello"); // 结果为 true
boolean endsWithWorld = str16.endsWith("World!"); // 结果为 true判断字符串是否相等
比较字符串是否相等时,不能使用 == 运算符,因为 == 运算符比较的是两个字符串对象的引用地址。应该使用 equals() 方法或 equalsIgnoreCase() 方法来判断两个字符串的内容是否相等。
使用 equals() 方法可以判断两个字符串的内容是否相等,equalsIgnoreCase() 方法则忽略大小写:
java
String str17 = "Hello";
String str18 = "hello";
boolean isEqual1 = str17.equals(str18); // 结果为 false
boolean isEqual2 = str17.equalsIgnoreCase(str18); // 结果为 true按字典顺序比较两个字符串
使用 compareTo() 方法可以按字典顺序比较两个字符串,该比较基于字符串中各个字符的 Unicode 值,按字典顺序将此 String 对象表示的字符序列与参数字符串所表示的字符序列进行比较。如果按字典顺序此 String 对象位于参数字符串之前,则比较结果为负数;如果按字典顺序此 String 对象位于参数字符串之后,则比较结果为正数;如果两个字符串相等,则比较结果为 0。
java
String str19 = "apple";
String str20 = "banana";
int result = str19.compareTo(str20); // 结果为负数,因为 "apple" 在 "banana" 之前字母大小写转换
使用 toLowerCase() 和 toUpperCase() 方法可以转换字符串的大小写。在转换时,数字或非字母字符不会被改变。
java
String str21 = "Hello, World!";
String lowerCaseStr = str21.toLowerCase(); // 结果为 "hello, world!"
String upperCaseStr = str21.toUpperCase(); // 结果为 "HELLO, WORLD!"字符串分割
使用 split() 方法可以根据指定的字符或字符串分割字符串,分割后的结果存储在字符串数组中。
- split(String sign):根据指定的字符或字符串分割字符串。其中,sign 可以使用正则表达式。如果想定义多个分隔符,可以使用
|连接。 - split(String sign, int limit):根据指定的字符或字符串分割字符串,最多分割 limit 次。
java
String str22 = "apple,banana,orange";
String[] fruits1 = str22.split(","); // 结果为 ["apple", "banana", "orange"]
String[] fruits2 = str22.split(",", 2); // 结果为 ["apple", "banana,orange"]格式化字符串
String 类的静态方法 format() 可以用来格式化字符串。format() 方法有两种重载形式:
- format(String format, Object... args):根据指定的格式字符串和参数返回一个格式化字符串。
- format(Locale l, String format, Object... args):根据指定的区域设置、格式字符串和参数返回一个格式化字符串。
- l:区域设置,用于格式化日期、时间等。
- format:格式字符串,包含格式化转换符。
- args:参数列表,用于替换格式字符串中的格式化转换符。
日期和时间字符串格式化
在程序设计中经常要现实日期和时间。在 Java 中,format() 方法通过给定特殊的转换符作为参数来实现对日期和时间的格式化。
日期格式化

表 常用的日期格式化转换符
示例:
java
import java.util.Date;
public class Main {
public static void main(String[] args) {
Date date = new Date();
String year = String.format("%tY", date); // 年份,结果为 "2023"
String month = String.format("%tm", date); // 月份,结果为 "10"
String day = String.format("%td", date); // 日期,结果为 "05"
}
}时间格式化

表 时间格式化转换符
示例:
java
import java.util.Date;
public class Main {
public static void main(String[] args) {
Date date = new Date();
String hour = String.format("%tH", date); // 24 小时制,结果为 "15"
String minute = String.format("%tM", date); // 分钟,结果为 "08"
String second = String.format("%tS", date); // 秒,结果为 "12"
}
}日期和时间的组合格式

表 常见的日期和时间的组合格式
示例:
java
import java.util.Date;
public class Main {
public static void main(String[] args) {
Date date = new Date();
String time = String.format("%tc", date); // 完整的日期和时间,结果为 "星期四 十月 05 15:08:12 CST 2023"
String form = String.format("%tF", date); // 年-月-日,结果为 "2023-10-05"
}
}常规类型格式化
常规类型的格式化可以应用于任何参数类型,通过下表所示的转换符来实现:

表 常规转换符
示例:
java
String str1 = String.format("%d", 400 / 2); // 整数,结果为 "200"
String str2 = String.format("%b", 3 > 2); // 布尔值,结果为 "true"
String str3 = String.format("%x", 200); // 十六进制,结果为 "c8"使用正则表达式
正则表达式通常被用于判断语句中,用来检查某一字符串是否满足某一个是。正则表达式是含有一些具有特殊含义的字符串,这些特殊的字符串称为正则表达式的元字符。
正则表达式中元字符及其含义如下表所示:

表 正则表达式中的元字符
在正则表达式中可以使用中括号([])来表示一个字符集合,其中的字符可以是单个字符,也可以是一个范围。例如,[abc]1 表示字符 a1、b1 或 c1,[a-z] 表示从 a 到 z 的任意字符。 中括号还可以为其他格式,如:
[^abc]:表示除了 a、b、c 之外的任意字符。[a-r]:表示从 a 到 r 的任意字符。[a-zA-Z]:表示从 a 到 z 或从 A 到 Z 的任意字符,这里即表示所有的英文字母。[a-e[m-p]]:表示 a 到 e 或 m 到 p 中的任意一个字符,这里即表示进行并集操作。[a-z&&[def]]:表示 a 到 z 且为 d、e、f 中的任意一个字符,这里即表示进行交集操作。[a-z&&[^bc]]:表示 a 到 z 且不为 b、c 中的任意一个字符,这里即表示进行差集操作。
在正则表达式中允许使用限定修饰符来限定元字符出现的次数。例如:A* 表示 A 出现 0 次或多次,A+ 表示 A 出现 1 次或多次,A? 表示 A 出现 0 次或 1 次,A{n} 表示 A 出现 n 次,A{n,} 表示 A 出现 n 次或多次,A{n,m} 表示 A 出现 n 到 m 次。
限定修饰符的用法如下表所示:

表 限定修饰符
在 Java 中,可以使用 matches() 方法来判断字符串是否匹配某个正则表达式:
java
String str = "Hello, World!";
boolean isMatch = str.matches("Hello.*"); // 结果为 true字符串生成器
由于 String 类是不可变的,创建成功的字符串对象其长度是固定的,内容不能被改变和编译。虽然使用 + 运算符和 concat() 方法可以连接字符串,但这会产生一个新的 String 实例,频繁的字符串操作会产生大量临时对象,影响性能。为此,Java 提供了 StringBuilder 和 StringBuffer 类,它们是可变的字符串类。
StringBuilder
StringBuilder 是非线程安全的,适用于单线程环境下的字符串操作:
- append(content):追加字符串,等价于
+运算符。javaStringBuilder sb = new StringBuilder(); sb.append("Hello"); sb.append(", "); sb.append("World!"); String result = sb.toString(); // 结果为 "Hello, World!" - insert(int offset, arg):在指定位置插入字符串。java
StringBuilder sb = new StringBuilder("Hello World!"); sb.insert(5, ", "); // 在索引 5 处插入 ", " String result = sb.toString(); // 结果为 "Hello, World!" - delete(int start, int end):删除指定位置的字符串。java
StringBuilder sb = new StringBuilder("Hello, World!"); sb.delete(5, 7); // 删除索引 5 到 7 的字符 String result = sb.toString(); // 结果为 "Hello World!"
StringBuffer
StringBuffer 是线程安全的,适用于多线程环境下的字符串操作:
java
StringBuffer sb = new StringBuffer();
sb.append("Hello");
sb.append(", ");
sb.append("World!");
String result = sb.toString(); // 结果为 "Hello, World!"