Java String 类

在 Java 中,String 类是最常用的类之一,用于表示和操作字符串。String 类在 java.lang 包中,不需要导入就能直接使用。今天我们就来深入了解 String 类的用法、常见方法、特点和注意事项!🚀


1️⃣ String 基本概念

  • String 是引用数据类型,但表现像基本数据类型一样简单。
  • String 对象是不可变的(immutable),一旦创建就无法修改。
  • String 底层是一个 char[] 字符数组,用于存储字符串内容。

声明字符串的方式:

1
2
3
4
5
// 使用双引号直接赋值(推荐)
String str1 = "Hello, JJ Lin";

// 使用构造方法(不推荐)
String str2 = new String("Hello, JJ Lin");

2️⃣ String 的不可变性(Immutable)

String 对象内容不可变,每次修改都会创建一个新的对象。

1
2
3
4
5
6
7
public class StringImmutable {
public static void main(String[] args) {
String str = "JJ Lin";
str = str + " - Not for anyone";
System.out.println(str); // 新创建了一个字符串对象
}
}

3️⃣ 常用方法

🔹 字符串长度

1
2
String str = "林俊杰";
System.out.println(str.length()); // 3

🔹 字符串拼接

1
2
3
4
5
6
7
String str1 = "JJ";
String str2 = " Lin";
String result = str1.concat(str2); // 推荐
System.out.println(result); // JJ Lin

// 使用 + 运算符(常用)
System.out.println(str1 + str2); // JJ Lin

🔹 字符串比较

1
2
3
4
5
6
7
8
String str1 = "JJ Lin";
String str2 = "JJ Lin";
String str3 = new String("JJ Lin");

System.out.println(str1 == str2); // true(字符串常量池,引用相同)
System.out.println(str1 == str3); // false(new 创建的对象地址不同)
System.out.println(str1.equals(str3)); // true(比较内容)
System.out.println(str1.equalsIgnoreCase("jj lin")); // true(忽略大小写比较)

🔹 字符串查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
String str = "Not for anyone";

// 判断是否包含
System.out.println(str.contains("anyone")); // true

// 字符首次出现索引
System.out.println(str.indexOf('o')); // 1

// 字符最后出现索引
System.out.println(str.lastIndexOf('o')); // 10

// 判断以什么开头/结尾
System.out.println(str.startsWith("Not")); // true
System.out.println(str.endsWith("one")); // true

🔹 字符串截取

1
2
3
4
5
6
7
String str = "JJ Lin";

// 从索引 3 开始截取
System.out.println(str.substring(3)); // Lin

// 截取索引 0 到 1(不包含 2)
System.out.println(str.substring(0, 2)); // JJ

🔹 字符串替换

1
2
3
String str = "JJ Lin";
System.out.println(str.replace('J', 'L')); // LL Lin
System.out.println(str.replaceAll("Lin", "Chou")); // JJ Chou

🔹 字符串大小写转换

1
2
3
String str = "JJ Lin";
System.out.println(str.toUpperCase()); // JJ LIN
System.out.println(str.toLowerCase()); // jj lin

🔹 去除首尾空格

1
2
String str = "  JJ Lin  ";
System.out.println(str.trim()); // "JJ Lin"

🔹 字符串拆分

1
2
3
4
5
6
String str = "JJ Lin, Jay Chou, Eason Chan";
String[] singers = str.split(", ");

for (String singer : singers) {
System.out.println(singer);
}

输出:

1
2
3
JJ Lin
Jay Chou
Eason Chan

4️⃣ String 特点

🔹 字符串常量池(String Pool)

Java 中字符串常量池是 JVM 内存中的一个特殊区域,专门存储字符串字面量,相同内容的字符串只存一份

1
2
3
4
String str1 = "JJ Lin";
String str2 = "JJ Lin";

System.out.println(str1 == str2); // true,指向同一个常量池对象

🔹 new 创建字符串

使用 new 会在堆内存中创建一个新对象,即使内容相同。

1
2
3
4
String str1 = "JJ Lin";
String str2 = new String("JJ Lin");

System.out.println(str1 == str2); // false,不是同一个对象

5️⃣ 字符串格式化

使用 String.format() 格式化字符串。

1
2
3
4
5
String name = "JJ Lin";
int age = 42;

String formatted = String.format("%s is %d years old.", name, age);
System.out.println(formatted); // JJ Lin is 42 years old.

6️⃣ 字符串与其他类型转换

🔹 基本类型转字符串

1
2
int num = 100;
String str = String.valueOf(num); // "100"

🔹 字符串转基本类型

1
2
String str = "100";
int num = Integer.parseInt(str); // 100

7️⃣ String 和 StringBuilder / StringBuffer 区别

特性 String StringBuilder StringBuffer
可变性 ❌ 不可变 ✅ 可变 ✅ 可变
线程安全 ❌ 非线程安全 ❌ 非线程安全 ✅ 线程安全
性能 🚀 性能较低 🚀🚀🚀 性能最高 🚀🚀 性能较高

8️⃣String 类方法表

String 类是 Java 中最常用的类之一,用于处理字符串。它是不可变的(immutable),每次对字符串的操作都会生成一个新的字符串对象。让我们来全面总结 String 类的常用方法吧!✨


🧱 1. 创建字符串

1
2
3
4
5
6
7
8
9
// 直接赋值
String str1 = "Hello, Java!";

// 使用构造方法
String str2 = new String("Hello, Java!");

// 字符数组转换为字符串
char[] chars = {'J', 'a', 'v', 'a'};
String str3 = new String(chars);

📏 2. 获取信息

方法 功能 示例
length() 获取字符串长度 "Java".length()4
charAt(int index) 获取指定索引处的字符 "Java".charAt(1)'a'
indexOf(String str) 查找子字符串首次出现位置 "Hello".indexOf("l")2
lastIndexOf(String str) 查找子字符串最后出现位置 "Hello".lastIndexOf("l")3
contains(CharSequence s) 判断是否包含子字符串 "Java".contains("av")true
startsWith(String prefix) 判断是否以指定前缀开头 "Java".startsWith("Ja")true
endsWith(String suffix) 判断是否以指定后缀结尾 "Java".endsWith("va")true
isEmpty() 判断字符串是否为空 "".isEmpty()true
isBlank()(Java 11+) 判断是否为空或仅包含空白字符 " ".isBlank()true

🔄 3. 字符串转换

方法 功能 示例
toUpperCase() 转换为大写 "java".toUpperCase()"JAVA"
toLowerCase() 转换为小写 "JAVA".toLowerCase()"java"
trim() 去除前后空格 " Java ".trim()"Java"
strip()(Java 11+) 去除前后空白字符,更强大 " Java ".strip()"Java"
replace(String old, String new) 替换所有匹配的子字符串 "Java".replace("a", "o")"Jovo"
replaceFirst(String regex, String replacement) 替换首个匹配项 "Java Java".replaceFirst("a", "o")"Jova Java"
replaceAll(String regex, String replacement) 使用正则替换所有匹配项 "Java Java".replaceAll("a", "o")"Jovo Jovo"
substring(int beginIndex) 截取从索引开始的字符串 "Java".substring(1)"ava"
substring(int begin, int end) 截取指定范围字符串(不含 end) "Java".substring(1, 3)"av"

🔗 4. 拼接字符串

方法 功能 示例
concat(String str) 拼接字符串 "Hello".concat(" World")"Hello World"
+(加号运算符) 拼接字符串(最常用) "Hello" + " World""Hello World"
String.join()(Java 8+) 使用分隔符拼接多个字符串 String.join(", ", "Java", "Python", "C++")"Java, Python, C++"

📋 5. 字符串拆分

方法 功能 示例
split(String regex) 使用正则表达式拆分字符串 "Java-Python-C++".split("-")["Java", "Python", "C++"]
split(String regex, int limit) 限制拆分次数 "Java-Python-C++".split("-", 2)["Java", "Python-C++"]

🧪 6. 比较字符串

方法 功能 示例
equals(String another) 判断内容是否相同(区分大小写) "Java".equals("java")false
equalsIgnoreCase(String another) 判断内容是否相同(不区分大小写) "Java".equalsIgnoreCase("java")true
compareTo(String another) 按字典顺序比较字符串大小 "Java".compareTo("Python")-6
compareToIgnoreCase(String another) 按字典顺序比较(忽略大小写) "Java".compareToIgnoreCase("java")0

🔍 7. 格式化字符串

方法 功能 示例
String.format(String format, Object... args) 格式化字符串 String.format("你好, %s!", "Alice")"你好, Alice!"

🔠 8. 转换为其他类型

方法 功能 示例
toCharArray() 转换为字符数组 "Java".toCharArray()['J', 'a', 'v', 'a']
getBytes() 转换为字节数组 "Java".getBytes()

💡 总结:

  • String 是最基础但最强大的类之一,必须熟练掌握。
  • 理解不可变性和字符串池,有助于编写高效代码
  • 遇到频繁拼接或修改字符串,建议使用 StringBuilder

Java String 类 语法练习题

基础题

1.判断一个字符串是否以 “Java” 开头且以 “!” 结尾。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.util.Scanner;
//判断一个字符串是否以 "Java" 开头且以 "!" 结尾。
public class Panduan {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
String result = input.startsWith("Java") && input.endsWith("!") ? "True" : "False";
System.out.print(result);
scanner.close();
}


}

1
2
3
4
Javaffffffffffffff!
True
fdssfa
False

2.将字符串中的所有空格去除。

1
2
3
4
5
6
7
8
9
10
import java.util.Scanner;

public class Rmspace {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
System.out.println(input.replaceAll(" ",""));
}
}

1
2
 fsdfsd    
fsdfsd

3.将用户输入的字符串转换为大写,并输出长度。

1
2
3
4
5
6
7
8
9
10
11
import java.util.Scanner;
//将用户输入的字符串转换为大写,并输出长度。
public class ToUppercase {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
String result = input.toUpperCase();
System.out.println(result + " 长度: " +result.length());
}

}
1
2
ddddddddddddddSSSSSSSSSS
DDDDDDDDDDDDDDSSSSSSSSSS 长度: 24

4.将一个以逗号分隔的字符串拆分,并逐行打印每个单词。

1
2
3
4
5
6
7
8
9
10
11
12
13
import java.util.Scanner;
//将一个以逗号分隔的字符串拆分,并逐行打印每个单词。
public class Splite {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
String[] result = input.split(",");
for(String strr : result){
System.out.println(strr);
}
}
}

1
2
3
4
5
dsdf,fsdf,Lin,JJ
dsdf
fsdf
Lin
JJ

5.判断两个字符串是否相等(不区分大小写)。

1
2
3
4
5
6
7
public class Equal {
public static void main(String[] args){
String st1 = "Java";
String st2 = "java";
System.out.println(st1.equalsIgnoreCase(st2));
}
}

9.统计某个字符出现次数

输入一个字符串和一个字符,统计这个字符在字符串中出现的次数。
输入示例:

1
2
JJ Lin is the best singer
J

输出示例:

1
字符 'J' 出现了 2 次

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.Scanner;

public class Count {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
System.out.print("请输入待检测的字符串: ");
String input = scanner.nextLine();
System.out.print("请输入目标检测字符: ");
char Des = Character.valueOf(scanner.nextLine().charAt(0));
int result = count(input,Des);
System.out.println("它出现的次数是:" + result);
}
public static int count(String str, char Des){
int cou = 0;
for(int i = 0;i<str.length();i++){
if (str.charAt(i) == Des){
cou++;
}
}
return cou;
}
}
1
2
3
请输入待检测的字符串: vsadddddd hgjeqhvf jklll
请输入目标检测字符: k
它出现的次数是:1

10.反转字符串

输入一个字符串,将它反转输出。
输入示例:

1
JJ Lin

输出示例:

1
niL JJ

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.util.Scanner;
// 输入一个字符串,将它反转输出。
public class Reverse {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
String input = scan.nextLine();
String result = reverse(input);
System.out.println(result);

}
public static String reverse(String str){
StringBuilder strlist = new StringBuilder();
for(int i = str.length() - 1 ; i>=0;i--){
strlist.append(str.charAt(i));
}
return strlist.toString();
}
}

1
2
sssssssssssssllllllll
llllllllsssssssssssss

进阶题

1.首字母大写

输入一个英文句子,将每个单词的首字母大写。

输入示例:

1
jj lin is amazing

输出示例:

1
Jj Lin Is Amazing
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.util.Scanner;
public class Upper1st {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
String[] strarrey = input.split(" ");
StringBuilder result = new StringBuilder();
for(String str:strarrey){
StringBuilder strr = new StringBuilder(str);
String Upperfirst = Character.toUpperCase(strr.charAt(0)) + strr.substring(1);
result.append(Upperfirst + " ");

}
String rr = result.toString();
String re = rr.strip();
System.out.println(re);

}
}

1
2
sdgbkab hjkkj nnnnn kljlhjjjjjjjjk jjk
Sdgbkab Hjkkj Nnnnn Kljlhjjjjjjjjk Jjk
发现的异常问题

当输入的字符串之间的空格的数量大于一时,如输入ss jj jj会报错:

1
2
3
4
5
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: index 0, length 0
at java.base/java.lang.String.checkIndex(String.java:4567)
at java.base/java.lang.AbstractStringBuilder.charAt(AbstractStringBuilder.java:351)
at java.base/java.lang.StringBuilder.charAt(StringBuilder.java:91)
at Upper1st.main(Upper1st.java:10)

java.lang.StringIndexOutOfBoundsException: index 0, length 0:字符串索引出界异常,原因是当输入字符串中存在多个连续空格时,split(" ") 会产生空字符串元素,例如输入 "kk jj jjj"split(" ") 会将其分割为 ["kk", "jj", "", "jjj"],其中包含一个空字符串 ""。当遍历到这个空字符串时,执行 strbuilder.charAt(0) 就会抛出 StringIndexOutOfBoundsException 异常。

解决方案

在处理每个分割后的字符串之前,先检查其长度是否大于 0,如果长度大于 0 再进行首字母大写的操作。

升级后的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.Scanner;
public class Upper1st {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
String[] strarrey = input.split(" ");
StringBuilder result = new StringBuilder();
for(String str:strarrey){
StringBuilder strbuilder = new StringBuilder(str);
if (str.length() > 0){
String Upperfirst = Character.toUpperCase(strbuilder.charAt(0)) + strbuilder.substring(1);
result.append(Upperfirst + " ");
}else{
continue;
}


}
String rr = result.toString().strip();
System.out.println(rr);
}
}

1
2
dddddddd   kkkkkkkk kkk  
Dddddddd Kkkkkkkk Kkk

2.判断字符串是否是回文(正读和反读都一样)

输入示例:

1
level

输出示例:

1
是回文字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.util.Scanner;

public class IsPalindrome {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
String[] input_list = input.split("");
boolean is_Palindrome = true;
int half = (input_list.length)/2;
for(int i = 0 ;i < half; i++){
if (input_list[i].equals(input_list[input_list.length - 1 - i])){
continue;
}else {
is_Palindrome = false;
break;
}
}
if (is_Palindrome){
System.out.println("该输入字符串是回文的");
}else {
System.out.println("该输入字符串不是回文的");
}
}
}


4.字符串压缩(类似 LeetCode 压缩字符串题)

把连续相同字符用字符+次数的形式表示。
输入示例:

1
aaabbcddd

输出示例:

1
a3b2c1d3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.util.Scanner;
// 字符串压缩(类似 LeetCode 压缩字符串题):把连续相同字符用字符+次数的形式表示。
public class CountUS {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
String[] input_array = input.split("");
String inputB = "";
for(int i =0;i < input_array.length;i++){
if (inputB.contains(input_array[i])){
continue;
}else {
inputB += input_array[i];
inputB += (input.lastIndexOf(input_array[i]) - input.indexOf(input_array[i])) + 1;
}
}
System.out.print(inputB);
}

}
1
2
aaaaaaaaaaaaddddddddddddffffffffffffffff
a12d12f16

问题分析

  1. 重复字符判断逻辑错误

在代码中,使用 inputB.contains(input_array[i]) 来判断当前字符是否已经处理过。这种判断方式有问题,因为只要字符在之前出现过就会跳过,而没有考虑字符是否连续。例如,当处理到第二个 a 时,由于 inputB 中已经包含了 a,就会跳过,导致后续的 a 不能正确统计。

  1. 字符计数逻辑错误

代码中使用 input.lastIndexOf(input_array[i]) - input.indexOf(input_array[i]) + 1 来计算字符的出现次数,这是错误的。这个表达式计算的是该字符在整个输入字符串中第一次出现和最后一次出现之间的距离加 1,而不是连续相同字符的个数。

升级代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.util.Scanner;

// 字符串压缩(类似 LeetCode 压缩字符串题):把连续相同字符用字符+次数的形式表示。
public class CountUS {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
StringBuilder result = new StringBuilder();

int count = 1;
for (int i = 0; i < input.length(); i++) {
// 如果不是最后一个字符,且当前字符和下一个字符相同
if (i < input.length() - 1 && input.charAt(i) == input.charAt(i + 1)) {
count++;
} else {
// 将当前字符添加到结果中
result.append(input.charAt(i));
// 将连续相同字符的个数添加到结果中
result.append(count);
// 重置计数器
count = 1;
}
}

System.out.println(result.toString());
}
}
1
2
assass
a1s2a1s2

5.找出字符串中最长的单词

输入示例:

1
JJ Lin is a phenomenal singer

输出示例:

1
phenomenal
1
2
3
4
5
6
7
8
9
10
11
12
import java.util.Arrays;
import java.util.Scanner;

public class Longest {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
String[] input = scanner.nextLine().split(" ");
Arrays.sort(input,(a,b) -> b.length() - a.length());
System.out.println(input[0]);
}
}

1
2
aaaaaa hkkjhjkh khhhhhhhhhhhhhhhhhhhhhhhh
khhhhhhhhhhhhhhhhhhhhhhhh

6.需求:输入一个句子,统计其中大写字母、小写字母、数字和空格的数量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.util.Scanner;

public class StringAnalysis {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入一个句子:");
String input = scanner.nextLine();

int upperCount = 0, lowerCount = 0, digitCount = 0, spaceCount = 0;

for (int i = 0; i < input.length(); i++) {
char ch = input.charAt(i);
if (Character.isUpperCase(ch)) {
upperCount++;
} else if (Character.isLowerCase(ch)) {
lowerCount++;
} else if (Character.isDigit(ch)) {
digitCount++;
} else if (Character.isWhitespace(ch)) {
spaceCount++;
}
}

System.out.printf("大写字母: %d,小写字母: %d,数字: %d,空格: %d%n",
upperCount, lowerCount, digitCount, spaceCount);
}
}

Bonus:综合练习题

编写一个程序,实现一个简单的文本分析工具,功能包括:

  • 统计总字数
  • 统计不同单词数量
  • 找出出现频率最高的单词
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import java.util.*;

public class TextAnalyzer {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要分析的文本:");
String text = scanner.nextLine();
scanner.close();

// 统计总字数
int totalCharacters = text.length();

// 预处理文本,将文本转换为小写并按非字母数字字符分割成单词
String[] words = text.toLowerCase().split("[^a-zA-Z0-9]+");

// 统计不同单词数量
Set<String> uniqueWords = new HashSet<>();
Map<String, Integer> wordFrequency = new HashMap<>();

for (String word : words) {
if (!word.isEmpty()) {
uniqueWords.add(word);
wordFrequency.put(word, wordFrequency.getOrDefault(word, 0) + 1);
}
}
int distinctWordCount = uniqueWords.size();

// 找出出现频率最高的单词
String mostFrequentWord = "";
int maxFrequency = 0;
for (Map.Entry<String, Integer> entry : wordFrequency.entrySet()) {
if (entry.getValue() > maxFrequency) {
maxFrequency = entry.getValue();
mostFrequentWord = entry.getKey();
}
}

// 输出结果
System.out.println("总字数: " + totalCharacters);
System.out.println("不同单词数量: " + distinctWordCount);
if (!mostFrequentWord.isEmpty()) {
System.out.println("出现频率最高的单词: " + mostFrequentWord + ",出现次数: " + maxFrequency);
} else {
System.out.println("未找到有效单词。");
}
}
}

💡 提示:

  • 多用 String 的方法如 charAt()indexOf()substring()split()replace()toUpperCase()equalsIgnoreCase() 等。
  • 可以用 StringBuilder 来处理字符串反转、拼接等操作,效率更高。
  • 利用 MapSet 等数据结构来统计和分析字符串。

🚀 有任何题目写不出来或者需要优化,随时喊我!加油 💪🌱✨

来源:

- ChatGPt-4o
- 我自己的题解和理解