一、String 类的概念以及特性
1、String 类的概念
String 类代表字符串,在 java.lang 包中。字符串是常量 ,用双引号引起来表示。 它的值在创建之后不能更改 。由 0 或多个字符组成,可以变相的理解成是一个由字符组成的数组。
2、String 类的特性
部分源码:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
由源码得知:
- String 类由 final 关键字修饰,代表不可变的字符序列 ;
- String 类实现了序列化、Comparable 接口和 CharSequence 接口;
- String 对象的字符内容是存储在一个 char 型的数组中。
二、常用方法一
- int length() 返回此字符串的长度
- char charAt(int index) 返回 char 指定索引处的值
- boolean isEmpty() 判断是否是空字符串
- String toLowerCase() 将 String 中的所有字符转换为小写
- String toUpperCase() 将 String 中的所有字符转换为大写
- boolean equalsIgnoreCase(String anotherString) 判断是否相等,忽略大小写
- boolean equals(Object obj) 比较字符串的内容是否相同
- String trim() 返回一个字符串,其值为此字符串,并删除任何前导和尾随空格
- String concat(String str) 将指定的字符串连接到该字符串的末尾
- String substring(int beginIndex) 返回一个字符串,该字符串是此字符串的子字符串
- String substring(int beginIndex, int endIndex) 返回一个新字符串,它是此字符串从 beginIndex 开始截取到 endIndex(不包含)的一个子字符串
- int compareTo(String anotherString) 按字典顺序比较两个字符串
测试代码:
public class StringMethodTest1 {
public static void main(String[] args) {
String s = "HelloWorld";
// int length() 返回此字符串的长度
System.out.println("字符串的长度:" + s.length()); // 10
// char charAt(int index) 返回 char指定索引处的值
System.out.println("索引为1位置上的字符:" + s.charAt(1)); // e
// boolean isEmpty() 判断是否是空字符串
System.out.println("是否是空字符串:" + s.isEmpty()); // false
// String toLowerCase() 将 String 中的所有字符转换为小写
System.out.println("转小写:" + s.toLowerCase()); // helloworld
// String toUpperCase() 将 String 中的所有字符转换为大写
System.out.println("转大写:" + s.toUpperCase()); // HELLOWORLD
// boolean equalsIgnoreCase(String anotherString) 判断是否相等,忽略大小写
String s1 = "HELLOworld";
System.out.println("忽略大小写比较:" + s.equalsIgnoreCase(s1)); // true
// boolean equals(Object obj) 比较字符串的内容是否相同
System.out.println("字符串比较:" + s.equals(s1)); // false
String s2 = " HelloChina ";
// String trim() 返回一个字符串,其值为此字符串,并删除任何前导和尾随空格
System.out.println("去掉首尾空格:" + s2.trim()); // HelloChina
// String concat(String str) 将指定的字符串连接到该字符串的末尾
System.out.println("字符串连接:" + s.concat(s2)); // HelloWorld HelloChina
// String substring(int beginIndex) 返回一个字符串,该字符串是此字符串的子字符串
System.out.println("截取子串1:" + s.substring(5)); // world
// String substring(int beginIndex, int endIndex) 返回一个新字符串,它是此字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串
System.out.println("截取子串2:" + s.substring(5, 8)); // wor
// int compareTo(String anotherString) 按字典顺序比较两个字符串
System.out.println("字典顺序比较两个字符串:" + s.compareTo(s1)); // 32
}
}
运行结果:
三、常用方法二
- boolean contains(CharSequence s) 当且仅当此字符串包含指定的 char 值序列时才返回 true
- int indexOf(String str) 返回指定子字符串第一次出现的字符串内的索引
- int indexOf(String str, int fromIndex) 返回指定子串的第一次出现的字符串中的索引,从指定的索引开始
- int lastIndexOf(String str) 返回指定子字符串最后一次出现的字符串中的索引
- int lastIndexOf(String str, int fromIndex) 返回指定子字符串的最后一次出现的字符串中的索引,从指定索引开始反向搜索
- boolean startsWith(String prefix) 测试此字符串是否以指定的前缀开头
- boolean startsWith(String prefix, int toffset) 测试在指定索引处开始的此字符串的子字符串是否以指定的前缀开头
- boolean endsWith(String suffix) 测试此字符串是否以指定的后缀结尾
测试代码:
public class StringMethodTest2 {
public static void main(String[] args) {
String s = "HelloWorld";
// boolean contains(CharSequence s) 当且仅当此字符串包含指定的char值序列时才返回true。
System.out.println("是否包含子串'or':" + s.contains("or")); // true
// int indexOf(String str) 返回指定子字符串第一次出现的字符串内的索引
System.out.println("子串'll'第一次出现的位置:" + s.indexOf("ll")); // 2
// int indexOf(String str, int fromIndex) 返回指定子串的第一次出现的字符串中的索引,从指定的索引开始
System.out.println("子串'o'出现的位置,从索引为5的位置开始查找:" + s.indexOf("o", 5)); // 6
// int lastIndexOf(String str) 返回指定子字符串最后一次出现的字符串中的索引。
System.out.println("子串'o'最后出现的索引位置:" + s.lastIndexOf("o")); // 6
// int lastIndexOf(String str, int fromIndex) 返回指定子字符串的最后一次出现的字符串中的索引,从指定索引开始反向搜索。
System.out.println("子串'o'最后一次出现的索引值:" + s.lastIndexOf("o", 5)); // 4
// boolean startsWith(String prefix) 测试此字符串是否以指定的前缀开头
System.out.println("判断是否以'He'开头:" + s.startsWith("He")); // true
// boolean startsWith(String prefix, int toffset) 测试在指定索引处开始的此字符串的子字符串是否以指定的前缀开头
System.out.println("判断索引为5的位置是否以'W'开头:" + s.startsWith("W", 5)); // true
// boolean endsWith(String suffix) 测试此字符串是否以指定的后缀结尾
System.out.println("判断是否以'ld'结尾:" + s.endsWith("ld")); // true
}
}
运行结果:
四、常用方法三
- String replace(char oldChar, char newChar) 字符串替换,返回一个新的字符串
- String replace(CharSequence target, CharSequence replacement) 将与字面目标序列匹配的字符串的每个子字符串替换为指定的字面替换序列
- boolean matches(String regex) 告诉这个字符串是否匹配给定的(regular expression)正则表达式
- String[] split(String regex) 将此字符串按给定的规则分割
测试代码:
public class StringMethodTest3 {
public static void main(String[] args) {
String s = "HelloWorld";
// String replace(char oldChar, char newChar) 字符串替换,返回一个新的字符串
System.out.println("使用'A'替换掉'H':" + s.replace("H", "A")); // AelloWorld
// String replace(CharSequence target, CharSequence replacement)
// 将与字面目标序列匹配的字符串的每个子字符串替换为指定的字面替换序列。
String s1 = s.replace("World", "China");
System.out.println("原字符串:" + s); // HelloWorld
System.out.println("替换后的字符串:" + s1); // HelloChina
// boolean matches(String regex) 告诉这个字符串是否匹配给定的 regular expression
String s2 = "123,456";
boolean matches = s2.matches("^[0-9]+$");//验证都是数字(至少有1个)
System.out.println("验证都是数字组成:" + matches); // false
// String[] split(String regex) 根据给定的正则表达式的匹配来拆分此字符串。形成一个新的String数组
String[] split = s2.split(",");
System.out.println("将字符串以 ',' 进行分割:");
for (String str : split) {
System.out.print(str + " "); // 123 456
}
}
}
运行结果:
五、String 与 StringBuffer、StringBuilder 的区别
通过以上 String 的学习,我们知道 String 的值是不可变的,这就导致每次对 String 的操作都会生成新的 String 对象,不仅效率低下,而且浪费大量优先的内存空间。所以从版本 JDK 5 开始,这个类别已经被一个等级类进行了补充,分别是 StringBuffer 和 StringBuilder。
StringBuffer 和 StringBuilder 都是可变类,和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象。每个StringBuffer / StringBuilder 对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量。
三者的区别:
- String 由 final 修饰,是不可变字符序列
- StringBuffer 可变字符序列,其效率低,但是线程安全
- StringBuilder 可变字符序列,其效率高,但是线程不安全