目录
一、定义与概述
二、创建字符串对象
2.1 直接赋值
2.2 使用构造函数
三、字符串的不可变性
四、常用方法
4.1 String对象的比较
4.1.1 ==比较是否引用同一个对象
4.1.2 boolean equals(Object anObject)方法:按照字典序比较
4.1.3 int compareTo(String s)方法: 按照字典序进行比较
4.1.4 int compareToIgnoreCase(String str)方法:
4.2 字符串查找
4.2 转化
4.3 字符串替换
4.4 字符串拆分
4.5 字符串截取
4.6 其他操作
五、StringBuilder和StringBuffer
一、定义与概述
在Java中,Sting类是用来表示字符串的。字符串是一个字符序列,例如"Hello, World! "。String类位于 java.lang 包中,这个包是Java语言的核心包之一,不需要显示导入就可以使用。
二、创建字符串对象
2.1 直接赋值
可以通过直接使用双引号来创建String对象,例如:String str = "Hello, World! " 。这种方式创建的字符串,在 Java 的字符串常量池中会检查是否已经存在相同内容的字符串。如果存在,就直接引用该字符串对象;如果不存在,则在常量池中创建一个新的字符串对象。
代码如下:
public class Test1 {
public static void main(String[] args) {
String str = "Hello, World! ";
}
}
2.2 使用构造函数
String():创建一个空字符串对象。例如:String str1 = new String();
String(String original): 使用另一个字符串来创建新的字符串对象。String str2 = new String("Another Java String");
String(char[] value): 通过字符数组来创建字符串,例如:char[] chars = {'h','e','l','l','o'};
String str3 = new String(chars); 这里str3的值就是"hello"。
上述代码:
public class Test1 {
public static void main(String[] args) {
String str = "Hello, World! ";
String str1 = new String();
String str2 = new String("Another Java String");
char[] chars = {'h','e','l','l','o'};
String str3 = new String(chars);
System.out.println(str1);
System.out.println(str2);
System.out.println(str3);
}
输出:
三、字符串的不可变性
String类是不可变的(immutable)。这意味着一旦一个String对象被创建,它的值就不能被改变。例如:
String str = "Java";
str = str + " is fun";
在这个例子中,看起来好像是改变了 str 的值,但实际上并不是。当执行 str = str + " is fun"这一行时,会创建一个新的 String 对象,其内容是 "Java is fun",然后 str 变量会指向这个新创建的对象,原来的 "Java" 字符串对象仍然存在于内存中(如果没有其他引用指向它,它会在适当的时候被垃圾回收)。
String类在设计时就是不可改变的,String类实现描述中已经说明了
1. String类被final修饰,表明该类不能被继承
2. value被修饰被final修饰,表明value自身的值不能改变,即不能引用其它字符数组,但是其引用空间中的内容可以修改。
四、常用方法
4.1 String对象的比较
4.1.1 ==比较是否引用同一个对象
注意:对于内置类型,==比较的是变量中的值;对于引用类型==比较的是引用中的地址。
public class Test2 {
public static void main(String[] args) {
int a=100;
int b=200;
int c=200;
// 对于基本类型变量,==比较两个变量中存储的值是否相同
System.out.println(a == b); //false
System.out.println(b == c); //true
System.out.println("===========");
// 对于引用类型变量,==比较两个引用变量引用的是否为同一个对象
String s1 = new String("hello");
String s2 = new String("hello");
String s3 = new String("world");
String s4 = s1;
System.out.println(s1 == s2); // false
System.out.println(s2 == s3); // false
System.out.println(s1 == s4); // true
}
}
输出:
如果写成下面的形式,会输出true。因为s5 创建后 hello会被放入字符串常量池,就会认为s5 和s6引用的时同一对象。
String s5 = "hello";
String s6 = "hello";
System.out.println(s5 == s6);
4.1.2 boolean equals(Object anObject)方法:按照字典序比较
String类重写了父类Object中equals方法,Object中equals默认按照==比较,String重写equals方法后。
下面是String类重写equals方法的实现规则
public class Test3 {
public static void main(String[] args) {
String s1 = new String("hello");
String s2 = new String("hello");
String s3 = new String("Hello");
System.out.println(s1.equals(s2));//true
System.out.println(s2.equals(s3));//false
}
}
输出截图:
equals比较:String对象中的逐个字符。虽然s1与s2引用的不是同一个对象,但是两个对象中放置的内容相同,因此输出true 。s1与s3引用的不是同一个对象,而且两个对象中内容也不同,因此输出false。
4.1.3 int compareTo(String s)方法: 按照字典序进行比较
与equals不同的是,equals返回的是boolean类型,而compareTo返回的是int类型。具体比较方式:
1. 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值。
2. 如果前k个字符相等(k为两个字符长度最小值),返回值两个字符串长度差值。
public class Test4 {
public static void main(String[] args) {
String s1 = new String("abc");
String s2 = new String("ac");
String s3 = new String("abc");
String s4 = new String("abcdef");
System.out.println(s1.compareTo(s2)); // 不同输出字符差值-1
System.out.println(s1.compareTo(s3)); // 相同输出 0
System.out.println(s1.compareTo(s4)); // 前k个字符完全相同,输出长度差值 -3
}
}
输出截图:
4.1.4 int compareToIgnoreCase(String str)方法:
与compareTo方式形同,但是忽略大小写。
public class Test5 {
public static void main(String[] args) {
String s1 = new String("abC");
String s2 = new String("Ac");
String s3 = new String("Abc");
String s4 = new String("ABcdef");
System.out.println(s1.compareToIgnoreCase(s2));
System.out.println(s1.compareToIgnoreCase(s3));
System.out.println(s1.compareToIgnoreCase(s4));
}
}
输出截图:
4.2 字符串查找
方法 | 功能 |
char charAt(int index) | 返回index位置上字符,如果index为负数或者越界,抛出 IndexOutOfBoundsException异常。 |
int indexOf(int ch) | 返回ch第一次出现的位置,没有返回-1 |
int indexOf(int ch, int fromIndex) | 从fromIndex位置开始找ch第一次出现的位置,没有返回-1 |
int indexOf(String str) | 返回str第一次出现的位置,没有返回-1 |
int indexOf(String str, int fromIndex) | 从fromIndex位置开始找str第一次出现的位置,没有返回-1 |
int lastIndexOf(int ch) | 从后往前找,返回ch第一次出现的位置,没有返回-1 |
int lastIndexOf(int ch, int fromIndex) | 从fromIndex位置开始找,从后往前找ch第一次出现的位置,没有返 回-1 |
int lastIndexOf(String str) | 从后往前找,返回str第一次出现的位置,没有返回-1 |
int lastIndexOf(String str, int fromIndex) | 从fromIndex位置开始找,从后往前找str第一次出现的位置,没有返 回-1 |
public class Test6 {
public static void main(String[] args) {
String s = "abccbaabccba";
System.out.println(s.charAt(2)); // 'c'
System.out.println(s.indexOf('c'));// 2
System.out.println(s.indexOf('a',2));// 5
System.out.println(s.indexOf("aa"));// 5
System.out.println(s.indexOf("cc",4));//8
System.out.println(s.lastIndexOf('c'));//9
System.out.println(s.lastIndexOf('b',11));//10
System.out.println(s.lastIndexOf("aa"));//5
System.out.println(s.lastIndexOf("aa",4));//-1
}
}
运行截图:
4.2 转化
1. 数值和字符串转化
class Student{
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "name=" + name + ", age=" + age ;
}
}
public class Test7 {
public static void main(String[] args) {
//其它类型转化成字符串
String s1 = String.valueOf(1000);
String s2 = String.valueOf('a');
String s3 = String.valueOf(12.34);
String s4 = String.valueOf(new Student("zhangsan",13));
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
System.out.println(s4);
//字符串转化数字
int data1 = Integer.parseInt("1234");
double data2 = Double.parseDouble("12.34");
System.out.println(data1);
System.out.println(data2);
}
}
运行截图:
2. 大小写转换
public class Test8 {
public static void main(String[] args) {
String s1 = "abc";
//小写转换大写
System.out.println(s1.toUpperCase());
String s2 = "ABC";
//大写转换小写
System.out.println(s2.toLowerCase());
}
}
运行截图:
3. 字符串转数组
public class Test9 {
public static void main(String[] args) {
String s = "hello";
//字符串转化数组
char[] chars = s.toCharArray();
for (char ch : chars) {
System.out.print(ch + " ");
}
System.out.println();
//数组转换字符串
char[] chars1 = {'w','o','r','l','d'};
String s1 = new String(chars1);
System.out.println(s1);
}
}
运行截图:
4. 格式化
public class Test9 {
public static void main(String[] args) {
String s = String.format("%d-%d-%d",2024,11,29);
System.out.println(s);
}
}
运行截图:
4.3 字符串替换
使用一个指定的新的字符串替换掉已有的字符串数据,可用的方法如下:
方法 | 功能 |
String replaceAll(String regex, String replacement) | 替换所有的指定内容 |
String replaceFirst(String regex, String replacement) | 替换首个内容 |
public class Test9 {
public static void main(String[] args) {
String s = "abccba";
System.out.println(s.replaceAll("c", "_"));
System.out.println(s.replaceFirst("c","-"));
}
}
运行截图:
注意事项: 由于字符串是不可变对象, 替换不修改当前字符串, 而是产生一个新的字符串。
4.4 字符串拆分
可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串。
方法 | 功能 |
String[] split(String regex) | 将字符串全部拆分 |
String[] split(String regex, int limit) | 将字符串以指定的格式,拆分为limit组 |
public class Test9 {
public static void main(String[] args) {
String s = "2024-11-29";
String[] strings = s.split("-");
for (String str :strings){
System.out.print(str+" ");
}
System.out.println();
String[] strings1 = s.split("-",2);
for (String str : strings1){
System.out.print(str+" ");
}
}
}
注意事项:
1. 字符"|","*","+"都得加上转义字符,前面加上"\\".
2. 而如果是"\",那么就得写成"\\\\".
3. 如果一个字符串中有多个分隔符,可以用"|"作为连字符.
多次拆分:
public class Test9 {
public static void main(String[] args) {
String s = "name=zhangsan&age=18";
String[] strings = s.split("&");
for (String str : strings){
String[] strings1 = str.split("=");
System.out.println(strings1[0]+" "+strings1[1]);
}
}
}
输出截图:
4.5 字符串截取
从一个完整的字符串之中截取出部分内容。
方法 | 功能 |
String substring(int beginIndex) | 从指定索引截取到结尾 |
String substring(int beginIndex, int endIndex) | 截取部分内容 |
public class Test9 {
public static void main(String[] args) {
String s = "abcdefghijk";
System.out.println(s.substring(5));
System.out.println(s.substring(3, 6));//左闭右开
}
}
运行截图:
注意事项:
1. 索引从0开始
2. 注意前闭后开区间的写法, substring(3, 6) 表示包含 3 号下标的字符, 不包含 6 号下标
4.6 其他操作
方法 | 功能 |
String trim() | 去掉字符串中的左右空格,保留中间空格 |
trim 会去掉字符串开头和结尾的空白字符(空格, 换行, 制表符等).
public class Test9 {
public static void main(String[] args) {
String s = " hello \t\t";
System.out.println(s);
System.out.println(s.trim());
}
}
运行截图:
五、StringBuilder和StringBuffer
因为String类是不能修改的,所有的修改都会创建新对象,效率非常低下,因此:尽量避免对String的直接需要,如果要修改建议尽量使用StringBuffer或者StringBuilder。
public class Demo1 {
public static void main(String[] args) {
//获得毫秒级时间戳
long start = System.currentTimeMillis();
String s = "";
for (int i = 0; i < 10000; i++) {
s += i;
}
long end = System.currentTimeMillis();
System.out.println(end - start);
start = System.currentTimeMillis();
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 1000; i++) {
stringBuilder.append(i);
}
end = System.currentTimeMillis();
System.out.println(end - start);
}
}
运行截图:
由于String的不可更改特性,为了方便字符串的修改,Java中又提供StringBuilder和StringBuffer类。这两个类大部分功能是相同的。
方法 | 功能 |
StringBuff append(String str) | 在尾部追加,相当于String的+=,可以追加:boolean、char、char[]、 double、float、int、long、Object、String、StringBuff的变量 |
char charAt(int index) | 获取index位置的字符 |
int length() | 获取字符串的长度 |
int capacity() | 获取底层保存字符串空间总的大小 |
void ensureCapacity(int mininmumCapacity) | 扩容 |
void setCharAt(int index, char ch) | 将index位置的字符设置为ch |
int indexOf(String str) | 返回str第一次出现的位置 |
int indexOf(String str, int fromIndex) | 从fromIndex位置开始查找str第一次出现的位置 |
int lastIndexOf(String str) | 返回最后一次出现str的位置 |
int lastIndexOf(String str, int fromIndex) | 从fromIndex位置开始找str最后一次出现的位置 |
StringBuff insert(int offset, String str) | 在offset位置插入:八种基类类型 & String类型 & Object类型数据 |
StringBuffer deleteCharAt(int index) | 删除index位置字符 |
StringBuffer delete(int start, int end) | 删除[start, end)区间内的字符 |
StringBuffer replace(int start, int end, String str) | 将[start, end)位置的字符替换为str |
String substring(int start) | 从start开始一直到末尾的字符以String的方式返回 |
String substring(int start,int end) | 将[start, end)范围内的字符以String的方式返回 |
StringBuffer reverse() | 反转字符串 |
String toString() | 将所有字符按照String的方式返回 |
String和StringBuilder最大的区别在于String的内容无法修改,而StringBuilder的内容可 以修改。频繁修改字符串的情况考虑使用StringBuilder。
注意:String和StringBuilder类不能直接转换。如果要想互相转换,可以采用如下原则:
String变为StringBuilder: 利用StringBuilder的构造方法或append()方法
StringBuilder变为String: 调用toString()方法。