字符串是由字符组成的不可变的Unicode字符序列。即String
对象一旦创建,其内容就不能被修改。String
类位于java.lang
包中,因此不需要导入即可直接使用。
字符串的创建
字符串可以通过多种方式创建:
字面量创建 :最常见的方式是通过双引号("
)创建字符串字面量。
ini
// 字面量创建
String str1 = "Hello, World!";
构造方法创建 :通过String
类的构造方法创建字符串对象。
ini
// 方式一:通过String类的构造方法创建 - 最简单的方式
String str2 = new String("Hello, World!");
// 方式二:使用字符创建
char[] chars = {'H', 'e', 'l', 'l', 'o'};
String str3 = new String(chars);
// 方式三:从字节数组创建
byte[] bytes = {'H', 'e', 'l', 'l', 'o'};
String str4 = new String(bytes);
// 方式四:从字节数组的部分范围创建
byte[] moreBytes = {97, 98, 99, 100, 101, 102};
String str5 = new String(moreBytes, 1, 3); // 取从索引1开始的三个字节
字符串特性
- 不可变性:一旦创建了一个字符串对象,其内容就不能被改变。这意味着每次对字符串进行拼接、替换等操作,都会生成一个新的字符串对象。
- 字符串池 :Java中有一项优化机制,即字符串池(String Pool),当创建字符串字面量时,JVM会先检查字符串池中是否存在相同的字符串,如果存在则直接引用,否则将新字符串添加到池中。通过
intern()
方法可以明确将字符串添加至字符串池。
字符串拼接
由于字符串的不可变性,连接字符串时会创建一个新的字符串对象。
ini
String part1 = "Java";
String part2 = "Programming";
// 使用加号(+)拼接
String concatenated = part1 + " " + part2;
// 或者使用String.join()方法
String joined = String.join(" ", part1, part2);
数组转字符串: StringBuilder
是一个可变的字符序列,它提供了append()
方法来高效地拼接字符串。使用StringBuilder
可以避免由于字符串不可变性导致的性能问题,特别是在频繁修改字符串内容的情况下。(例如:)
ini
String[] Strings = {"a", "b", "c", "d", "e", "f", "g", "h,i,j,k"};
// 创建StringBuilder对象
StringBuilder sb = new StringBuilder();
for (String str : Strings) {
// 使用append()方法拼接字符串
sb.append(str);
}
// 将StringBuilder对象转换为字符串
String result = sb.toString();
常用方法
字符串操作
length()
:返回字符串中的字符数量,即字符串的长度。
ini
// 创建一个字符串实例
String str = "Hello, World!";
// 使用 length() 方法获取字符串长度
int length = str.length();
System.out.println("str的长度: " + length); // 输出:13
charAt(int index)
:返回指定索引位置处的字符。注意,索引是从0开始的。
rust
// 创建一个字符串实例
String str = "Hello, World!";
// 使用 charAt() 方法获取指定索引位置的字符
char firstChar = str.charAt(0);
System.out.println("str的第一个字符: " + firstChar); // 输出:H
substring(int beginIndex, int endIndex)
:返回一个新字符串,它是原字符串的一部分,从指定的beginIndex
起始索引(包含)到endIndex
结束索引(不包含)。
rust
// 创建一个字符串实例
String str = "Hello, World!";
// 使用 substring() 方法获取子串
String subString = str.substring(7, 12);
System.out.println("获取子串: " + subString); // 输出:World
concat(String otherString)
:将当前字符串与提供的字符串拼接起来,形成一个新的字符串,原字符串不会被改变。
rust
// 创建一个字符串实例
String str = "Hello, World!";
// 使用 concat() 方法连接两个字符串
String appendedStr = str.concat(", 你好 Java!");
System.out.println("concat连接两个字符串: " + appendedStr); // 输出:Hello, World!, 你好 Java!
replace(CharSequence target, CharSequence replacement)
:查找字符串中所有出现的目标序列,并将其替换为给定的新字符串。
rust
// 创建一个字符串实例
String str = "Hello, World!";
// 使用 replace() 方法替换字符串中的部分字符或子串
String replacedStr = str.replace("World", "Java");
System.out.println("Replaced string: " + replacedStr); // 输出:Hello, Java!
比较
equals(Object obj)
或 :比较两个字符串的内容是否相等。区分大小写。
ini
String str1 = "hello";
String str2 = "hello";
boolean isEqual = str1.equals(str2);
System.out.println(isEqual); // 输出:true
String str3 = "Hello";
boolean isEqualCaseSensitive = str1.equals(str3);
System.out.println(isEqualCaseSensitive); // 输出:false
equalsIgnoreCase(String anotherString)
:类似于equals()
方法,但它在比较时忽略字符的大小写。
ini
String str1 = "hello";
String str3 = "Hello";
boolean isEqualIgnoreCase = str1.equalsIgnoreCase(str3);
System.out.println(isEqualIgnoreCase); // 输出:true
-
compareTo(String anotherString)
:按照字典顺序比较两个字符串。- 返回值如果是
正数
,则表示当前字符串大于另一个字符串; - 返回值如果为
负数
,则小于另一个字符串; - 返回值如果等于
0
,则表示两者相等;
- 返回值如果是
ini
String str1 = "apple";
String str2 = "banana";
int comparisonResult = str1.compareTo(str2);
System.out.println(comparisonResult); // 输出:-1 (因为 'a' 到 'b' 的ASCII差值加上后续字符的差异)
String sameStr = "apple";
int sameComparison = str1.compareTo(sameStr);
System.out.println(sameComparison); // 输出:0
startsWith(String prefix)
:检查当前字符串是否以指定的前缀开始。
ini
String sentence = "Hello, world!";
boolean startsWithHello = sentence.startsWith("Hello");
System.out.println(startsWithHello); // 输出:true
boolean notStartsWithGoodbye = sentence.startsWith("Goodbye");
System.out.println(notStartsWithGoodbye); // 输出:false
endsWith(String suffix)
:检查当前字符串是否以指定的后缀结束。
ini
String sentence = "Hello, world!";
boolean endsWithExclamation = sentence.endsWith("!");
System.out.println(endsWithExclamation); // 输出:true
boolean notEndsWithQuestion = sentence.endsWith("?");
System.out.println(notEndsWithQuestion); // 输出:false
查找
-
indexOf(int ch)
:查找指定字符在字符串中首次出现的索引位置。- 如果字符在字符串中存在,则返回它在字符串中的索引(位置从 0 开始计数),空格也会被算进来;
- 如果字符不存在于字符串中,则返回 -1。
ch
:这是要查找的字符,以整数形式表示,通常通过 Unicode 编码点(code point)来确定字符。
perl
String str = "Hello, World!";
char searchChar = 'W';
// 使用 int 值来查找字符 'W' 的索引位置
int index = str.indexOf((int) searchChar);
if (index != -1) {
System.out.println("'" + searchChar + "' 在字符串中的索引位置是: " + index); // 'W' 在字符串中的索引位置是: 7
} else {
System.out.println("'" + searchChar + "' 不在字符串中");
}
-
indexOf(String str)
:查找指定字符串在当前字符串中首次出现的位置.- 如果找到,返回值是匹配子串的
起始索引
; - 如果找不到匹配的子串,则返回
-1
; str
:要在当前字符串中查找的子字符串。
- 如果找到,返回值是匹配子串的
arduino
// 创建一个字符串
String fullString = "Hello, welcome to the world of Java programming.";
// 定义要查找的子字符串
String searchString = "welcome";
// 使用 indexOf 方法查找子字符串的位置
int index = fullString.indexOf(searchString);
// 输出结果
if (index != -1) {
System.out.println("'" + searchString + "' 在 '" + fullString + "' 中的位置是: " + index);
} else {
System.out.println("'" + searchString + "' 在 '" + fullString + "' 中未找到");
}
-
contains(CharSequence s)
:判断字符串是否包含指定的字符序列(CharSequence),区分大小写。如果你想进行不区分大小写的检查,可以先将字符串转换为统一的大写或小写再进行比较。CharSequence s
:这是一个表示字符序列的接口,它可以是String
对象或其他实现了CharSequence
接口的类实例,如StringBuilder
或CharBuffer
。
arduino
// 创建一个字符串
String fullString = "Hello, welcome to the world of Java programming.";
// 检查字符串是否包含子字符串 "welcome"
boolean containsWelcome = fullString.contains("welcome");
// 输出结果
System.out.println("'welcome' 是否在 '" + fullString + "' 中? " + containsWelcome);
// 检查字符串是否包含子字符串 "C++"
boolean containsCpp = fullString.contains("C++");
// 输出结果
System.out.println("'C++' 是否在 '" + fullString + "' 中? " + containsCpp);
分割与拼接
-
split(String regex)
:根据正则表达式分割字符串,返回字符串数组。regex
:这是一个正则表达式,用于定义如何分割字符串。例如,.
表示任何字符,\s
表示空白字符,,
表示逗号等。
注意事项:
- 默认情况下,此方法会尽可能多地进行分割,即贪婪模式。若想限制分割次数,可以使用
split(String regex, int limit)
版本,其中limit
参数用于指定最大分割片段数。 - 空字符串作为分隔符不会产生额外的空字符串元素,只有相邻的分隔符才会产生一个空字符串。
arduino
// 示例字符串
String str = "Hello,World,Java,Programming";
// 使用逗号作为分隔符进行分割
String[] words = str.split(",");
// 输出分割后的子字符串数组
for (String word : words) {
System.out.println(word);
}
-
join(CharSequence delimiter, Iterable<? extends CharSequence> elements)
:Java 8及以上版本引入的一个便捷方法,用于将一系列字符串(或者实现了CharSequence
接口的对象)连接成一个单一的字符串,其间用指定的分隔符进行间隔。delimiter
:这是一个CharSequence
类型的对象,代表用于分隔各个元素的字符序列。它可以是一个字符串或者其他任何实现了CharSequence
接口的对象,比如String
、StringBuilder
或CharBuffer
等。elements
:这是一个实现了Iterable
接口的对象,通常是一个集合,如List<String>
、Set<String>
或者数组,它包含了待连接的元素,这些元素必须是CharSequence
类型或其子类型。
arduino
// 创建一个字符串列表
List<String> fruits = Arrays.asList("Apple", "Banana", "Cherry");
// 使用逗号作为分隔符,将列表中的字符串连接起来
String joinedString = String.join(",", fruits);
// 输出连接后的字符串
System.out.println(joinedString); // 输出:Apple,Banana,Cherry
大小写转换
-
toLowerCase()
和toUpperCase()
:分别用于将字符串中的字符转换为其小写或大写形式,并返回一个新的字符串。- 由于在Java中字符串是不可变的,所以这两个方法并不会修改原始字符串,而是创建一个新的字符串对象。
toLowerCase()
方法: 将字符串中的所有大写字母转换为相应的小写字母。
ini
String str = "Hello, World!";
// 大写转小写
String lowerCaseStr = str.toLowerCase();
System.out.println(lowerCaseStr); // 输出:hello, world!
toUpperCase()
方法: 将字符串中的所有小写字母转换为对应的大写字母。
ini
String str = "Hello, World!";
// 小写转大写
String upperCaseStr = str.toUpperCase();
System.out.println(upperCaseStr); // 输出:HELLO, WORLD!
其他操作
trim()
:删除字符串两端的空白字符(空格、制表符、换行符等)。这个方法不会改变原始字符串,而是返回一个新的字符串,该字符串是原始字符串经过修剪后的结果。
ini
// 创建一个带有前后空白字符的字符串
String strWithSpaces = " Hello, World! ";
// 使用trim()方法去除前后空白
String trimmedStr = strWithSpaces.trim();
// 输出原始字符串和修剪后的字符串
System.out.println("原始字符串: " + strWithSpaces);
System.out.println("修改后的字符串: " + trimmedStr);
-
getBytes(String charsetName)
:将字符串转换为字节数组。- Java字符串内部采用Unicode编码存储,
getBytes()
方法将这些Unicode字符转换为字节序列,具体使用的编码取决于方法的重载形式。
- Java字符串内部采用Unicode编码存储,
不带参数形式代码示例:
ini
String str = "Hello, World!";
byte[] bytes = str.getBytes();
for (byte b : bytes) {
System.out.print(Integer.toHexString(b & 0xFF) + " ");
}
带参数形式代码示例:
ini
String str = "Hello, World!";
try {
byte[] Bytes = str.getBytes("UTF-8");
System.out.println(Arrays.toString(Bytes));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
-
intern()
:将字符串加入到 JVM 的字符串常量池(String Pool)中,返回字符串在字符串池中的引用。- 字符串常量池是一个特殊的内存区域,用于存储唯一的字符串字面量和通过
intern()
方法加入的字符串对象引用。 - 这样做的主要优点在于节省内存空间,特别是对于重复出现的字符串,可以确保在整个JVM中只有一个实例存在。
- 字符串常量池是一个特殊的内存区域,用于存储唯一的字符串字面量和通过
方法使用:
- 当调用
intern()
方法时,如果常量池中已经有了一个与当前字符串内容相同的字符串,则该方法返回常量池中已有字符串的引用。 - 如果常量池中没有相同内容的字符串,则将当前字符串添加到常量池,并返回常量池中新添加字符串的引用。
代码示例:
ini
// 创建两个内容相同的字符串
String str1 = new String("Java");
String str2 = "Java";
// 不调用intern()方法时,str1和str2指向不同的对象
System.out.println(str1 == str2); // 输出:false
// 调用intern()方法将str1加入常量池
str1 = str1.intern();
// 现在str1和str2指向常量池中同一个字符串对象
System.out.println(str1 == str2); // 输出:true
// 另一个示例,即使字符串是通过字符串拼接产生的
String str3 = new String("Ja") + new String("va");
str3 = str3.intern();
System.out.println(str3 == "Java"); // 输出:tru