Java 的 String
类是最常用的类之一,它用于表示不可变的字符序列。在 Java 中,字符串被视为对象,并且 String
类提供了丰富的构造方法和操作方法来处理字符串。下面我们将详细讲解 String
类的构造方法、比较、查找、转化、替换、拆分、截取等操作。
1. String 是引用类型
在 Java 中,String
是引用类型,它与基本数据类型(如 int
、char
等)不同。引用类型意味着 String
对象并不直接存储字符串的字符内容,而是通过引用指向堆内存中存储的字符数组。你提供的图片展示了 String
的源码:
private final char value[];
private int hash; // 默认为 0
解释:
-
char[] value
:String
类内部使用一个char[]
数组来存储实际的字符序列。这个char[]
数组是final
的,意味着一旦String
对象创建后,字符数组的引用是不可改变的,这也保证了String
的不可变性(String
对象一旦创建,其内容无法改变)。 -
int hash
:hash
是缓存字符串的哈希值。当我们调用hashCode()
方法时,Java 会计算字符串的哈希值并缓存到这个变量中。哈希值在字符串比较和哈希表(如HashMap
)操作中经常使用。
String 是不可变对象:
- 不可变性:
String
在 Java 中是不可变的,也就是说一旦创建了一个String
对象,它的内容就无法改变。如果你对字符串进行了任何操作(如拼接、替换),Java 会创建一个新的String
对象,而不是修改原来的字符串。public static void main(String[] args) { // s1和s2引用的是不同对象 s1和s3引用的是同一对象 String s1 = new String("hello"); String s2 = new String("world"); String s3 = s1; System.out.println(s1.length()); // 获取字符串长度---输出5 System.out.println(s1.isEmpty()); // 如果字符串长度为0,返回true,否则返回false }
解析:
String s1 = new String("hello");
创建了一个新的String
对象,存储的字符是"hello"
。该字符串存储在堆内存中,并且s1
引用的是这个堆内存地址。String s2 = new String("world");
创建了另一个String
对象,存储的字符是"world"
,与s1
引用的对象不同。String s3 = s1;
,这句代码使s3
和s1
引用同一个String
对象。
2. String
构造方法
String
类有多个构造方法,用于创建字符串对象。常见的构造方法包括:
public static void main(String[] args) {
// 使用常量串构造
String s1 = "hello bit";
System.out.println(s1);// 直接newString对象
String s2 = new String("hello bit");
System.out.println(s1);// 使用字符数组进行构造
char[] array = {'h','e','l','l','o','b','i','t'};
String s3 = new String(array);
System.out.println(s1);
}
3. String 比较
使用 ==
比较的是引用地址,如果两个 String
引用指向的是同一个对象,它们才会返回 true
。
String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2); // true, 因为它们指向同一个常量池中的对象
使用 equals()
:equals()
比较的是内容,即两个字符串的字符序列是否相等。
String s3 = new String("hello");
System.out.println(s1.equals(s3)); // true, 虽然对象不同,但内容相同
compareTo()
方法:比较两个字符串的字典顺序,返回:
- 0:表示两个字符串相等。
- 负数:表示调用的字符串小于比较的字符串。
- 正数:表示调用的字符串大于比较的字符串。
String s1 = "apple";
String s2 = "banana";
System.out.println(s1.compareTo(s2)); // 输出负数,表示 apple < banana
4. String 查找
indexOf()
:查找字符或子字符串第一次出现的位置。
String s = "Hello World";
int index = s.indexOf('o'); // 返回 4
int index2 = s.indexOf("World"); // 返回 6
lastIndexOf()
:查找字符或子字符串最后一次出现的位置。
int lastIndex = s.lastIndexOf('o'); // 返回 7
5. String 转化
大小写转换:
String lower = s.toLowerCase(); // 转换为小写
String upper = s.toUpperCase(); // 转换为大写
String.valueOf()
:将其他类型的数据(如 int
、double
、char[]
)转换为字符串。
int num = 100;
String str = String.valueOf(num); // "100"
6. String 替换
replace()
:替换指定字符或字符串。
String s = "Hello World";
String replaced = s.replace('l', 'p'); // "Heppo Worpd"
String replaced2 = s.replace("World", "Java"); // "Hello Java"
replaceAll()
:支持正则表达式替换。
String replaced3 = s.replaceAll("\\s", "_"); // 用下划线替换空格:"Hello_World"
7. String 拆分
split()
:根据正则表达式拆分字符串。
String s = "apple,banana,cherry";
String[] fruits = s.split(","); // {"apple", "banana", "cherry"}
split()
带限制:你可以通过传递第二个参数指定拆分的最大次数。
String[] limitedFruits = s.split(",", 2); // {"apple", "banana,cherry"}
8. String 截取
substring()
:提取子字符串。
String s = "Hello World";
String sub = s.substring(6); // 从索引 6 开始截取:"World"
String sub2 = s.substring(0, 5); // 从索引 0 开始,截取到 5(不包含 5):"Hello"
总结
String
是不可变引用类型,其内部使用char[]
存储字符序列,并且通过哈希值缓存优化字符串操作。String
提供了丰富的构造方法用于不同数据源的字符串创建。- 比较字符串时,
==
比较的是引用地址,equals()
比较的是内容,compareTo()
用于字典顺序比较。 String
提供了丰富的查找、转化、替换、拆分和截取操作,使得字符串处理非常方便。