目录
4、 认识StringBuffer和StringBuilder
1、String类的重要性
在C语言中已经涉及到字符串了,但是在C语言中要表示字符串只能使用字符数组或者字符指针,可以使用标准库提供的字符串系列函数完成大部分操作,但是这种将数据和操作数据方法分离开的方式不符合面相对象的思想,而字符串应用又非常广泛,因此Java语言专门提供了String类。
在开发和校招笔试中,字符串也是常客,而且在面试中也频繁被问到,比如:String、StringBuff和StringBulider之间的区别等。
2、常用方法
2、1 字符串构造
String类提供的构造方法常用的是以下三种:
- 使用常量字符串构造
- 直接newString类对象
- 使用字符数组进行构造
public class Test { public static void main(String[] args) { //1、使用常量字符串构造 String str1="Hello"; //2、直接newString类对象 String str2=new String("Hello"); //3、使用字符数组进行构造 char[] array={'H','e','l','l','o'}; String str3=new String(array); } }
【注意】
1、String类是引用类型,内部并不储存字符串本身
2、Java中""引起来的也是String类对象
2、2 String对象的比较
1、==比较是否为同一个对象
对于内置类型,==是比较变量的值,而引用类型==比较的是引用中的地址。
String str1="Hello"; String str2=new String("Hello"); System.out.println(str1==str2);//结果为false
2、boolean equals(Obeject anObeject)方法,比较内容是否相同
String类重写了父类Object中equals方法,Object中equals默认按照==比较,String重写equals方法后,按照如下规则进行比较,比如:str1.equals(str2)
String str1="Hello"; String str2=new String("Hello"); String str3="world"; System.out.println(str1.equals(str2));//true System.out.println(str1.equals(str3));//false
3、int compareTo(String s)方法:按照字典序比较
与equals不同的是,equals返回的是boolean类型,而compareTo返回的是int类型。具体比较方式:
- 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值
- 如果前K个字符相等,返回两串字符串长度差值
4、int compareTolgnoreCase(String str)方法:与compareTo方法相同,但忽略大小写比较
String str1="abc"; String str2=new String("ABC"); String str3="Abdef"; System.out.println(str1.compareToIgnoreCase(str2));//0 System.out.println(str1.compareToIgnoreCase(str3));//-1 System.out.println(str2.compareToIgnoreCase(str3));//-1
2、3 字符串查找
方法 | 功能 |
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 |
String str1="Hello,world,Hello";//长度为17 System.out.println(str1.charAt(6));//w System.out.println(str1.indexOf('o'));//4 System.out.println(str1.indexOf('l',8));//9 System.out.println(str1.indexOf("Hello"));//0 System.out.println(str1.indexOf("Hello",0));//0 System.out.println(str1.lastIndexOf('l'));//15 System.out.println(str1.lastIndexOf('l',16));//15 System.out.println(str1.lastIndexOf("Hello"));//12 System.out.println(str1.lastIndexOf("Hello",10));//0
上述方法都是实例方法
2、4字符转换
数值和字符串转换:
- valueOf用于将其他形式转化为字符串,有许多重载方法。
代码演示:
public class Student { String name; int age; public Student(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }public class Test { public static void main(String[] args) { String str1=String.valueOf(123); String str2=String.valueOf(true); String str3=String.valueOf(new Student("lisi",18)); System.out.println(str1);//123 System.out.println(str2);//true System.out.println(str3);//Student{name='lisi', age=18} } }
大小写转化:
- 大写转小写toLowerCase()
- 小写转大写toUpperCase()
String str1="Hello"; String str2="World"; //小写转大写 System.out.println(str1.toUpperCase());//HELLO //大写转小写 System.out.println(str2.toLowerCase());// world
字符串转数组:
- toCharArray()
String str1="Hello"; char[]array = str1.toCharArray(); for (int i = 0; i < array.length; i++) { System.out.println(array[i]); }
格式转化:
- format
String s=String.format("%d-%d-%d",2024,7,5); System.out.println(s);//2024-7-5
2、5 字符串替换
使用一个指定的新的字符串替换已有的字符串数,可用方法如下:
方法 | 功能 |
String replaceAll(String regex, String replacement) | 替换所有的指定内容 |
String replaceFirst(String regex, String replacement) | 替换收个内容方法 |
代码示例:
String str1="Helloworld"; System.out.println(str1.replace("H","h")); System.out.println(str1.replaceFirst("l","L"));
【注意】由于字符串是不可变对象, 替换不修改当前字符串, 而是产生一个新的字符串.
2、6字符串拆分
可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串。
可用方法如下:
方法 | 功能 |
String[] split(String regex) | 将字符串全部拆分 |
String[] split(String regex,int limit) | 将字符串以定义的格式,拆分为limit组 |
代码实例:
【注意】
有些特殊字符作为分隔符无法正确切分,需要加上转义。
- " | "、" * "、 "+"都得加上转义字符,前面加上"\\"
- " \ "前面要加上" \\\\"
- 如果有多个分隔符,用" | "作为连字符
2、7 字符串截取
从一个完整的字符串之中截取部分内容,可用方法
方法 | 功能 |
String substring ( int beginindex ) | 从指定索引截取到结尾 |
String substring(int bwginindex ,int endindex ) | 截取部分内容 |
【注意】
- 索引从0开始
- 注意前闭后开的用法 substring( , 】
3、String字符串的不可变性
String类是一种不可变对象,字符串中内容是不可改变的。这是因为
1、String类在设计时就是不可改变的
String类中的字符实际保存在内部维护的value字符数组中,该图还可以看出:
- String类被final修饰,表明该类不能被继承
- value被修饰被final修饰,表明value自身的值不能改变,即不能引用其它字符数组,但是其引用空间中的内容可以修改。
2. 所有涉及到可能修改字符串内容的操作都是创建一个新对象,改变的是新对象
” 字符串不可变是因为其内部保存字符的数组被final修饰了,因此不能改变。”
这种说法是错误的,不是因为String类自身,或者其内部value被final修饰而不能被修改。
final修饰类表明该类不想被继承,final修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内容是可以修改的。
4、 认识StringBuffer和StringBuilder
4、1StringBuffer
StringBuffer类是Java提供的一个可变字符串序列类,在java.lang包中定义。它与String类相似,但有一个重要的区别:String类是不可变的,即创建后不能更改其内容,而StringBuffer类则可以在原地修改字符串。
需要注意的是,由于StringBuffer是为了线程安全而设计的。在多线程环境下,建议使用线程安全的StringBuffer类,以确保数据的一致性。
4、2StringBuilder
StringBuilder类是Java提供的一个可变字符串序列类,与StringBuffer类类似,但不同的是StringBuilder不是线程安全的。StringBuilder类位于java.lang包中。
以下是StringBuilder类的一些重要特性:
在单线程环境下,通过使用StringBuilder类,我们可以方便地进行字符串的动态操作和修改,并能够高效地处理字符串操作的需求。
面试题:String、StringBuffer和StringBuilder的异同?
相同点:底层都是通过char数组实现的
不同点:String对象一旦创建,其值是不能修改的,如果要修改,会重新开辟内存空间来存储修改之后的对象;而StringBuffer和StringBuilder对象的值是可以被修改的;
StringBuffer几乎所有的方法都使用synchronized实现了同步,线程比较安全,在多线程系统中可以保证数据同步,但是效率比较低;而StringBuilder 没有实现同步,线程不安全,建议在单线程中使用 StringBuilder,效率比较高。
如果我们在实际开发过程中需要对字符串进行频繁的修改,不要使用String,否则会造成内存空间的浪费;当需要考虑线程安全的场景下使用 StringBuffer,如果不需要考虑线程安全,追求效率的场景下可以使用 StringBuilder。