目录
1. String类的重要属性
2. 常用方法
2.1 字符串构造
2.2 String对象的比较
2.3 字符串查找
2.4 转化
2.5 字符串的不可变性
2.6 字符串修改
3. StringBuilder和StringBuffer
3.1 StringBuilder的介绍
3.2 区别
1. String类的重要属性
? 在C语言中已经涉及到字符串,但是在c语言中表示字符串只能使用字符数组或字符指针,可以使用标准库提供的字符串系列函数完成大部分操作,但这种将数据和操作数据分离开的方式不符合面向对象的思想,而字符串应用又非常广泛,因此Java专门提供了String类。
在开发和校招中,字符串也是常客,面试中也被频繁问到,比如String,StringBuffer,StringBuilder之间的区别等。
2. 常用方法
2.1 字符串构造
String类常用的构造方式有以下三种:
public static void main(String[] args) {
//使用常量串构造
String s1 = "hello word";
System.out.println(s1);
//直接newString对象
String s2 = new String("hello china");
System.out.println(s2);
//使用字符数组进行构造
char[] array = {'h','e','l','l','o'};
String s3 = new String(array);
System.out.println(s3);
}
注意:
1. String是引用类型,内部并不存储字符串本身,在String类的实现源码中,String类的实例变量如下:

//s1和s2引用的不是同一对象,s1和s3引用的是同一对象
String s1 = new String("hello");
String s2 = new String("world");
String s3 = s1;
System.out.println(s1.length()); //获取字符串长度
System.out.println(s1.isEmpty()); //如果字符串长度为0返回true,否则返回false

?2. 在Java中“ ”引起来的也是String类型对象
//打印“hello”字符串的长度
System.out.println("hello".length());
2.2 String对象的比较
1. == 比较是否引用同一个对象
注意:对于基本类型,==比较变量中的值,对于引用类型,==比较引用的地址
int a = 10;
int b = 20;
int c = 10;
//基本类型比较变量的值
System.out.println(a==b);
System.out.println(a==c);
String s1 = new String("hello");
String s2 = new String("world");
String s3 = new String("hello");
String s4 = s1;
//对于引用变量,比较的是引用的地址
System.out.println(s1==s2); //false
System.out.println(s1==s3); //false
System.out.println(s1==s4); //true
2. boolean equals(Object anObject)方法:按照字典序比较---字符大小的顺序
String类重写了父类Object中equals方法,Object中equals默认按照==比较,String类重写equals后,按照如下规则进行比较,比如:s1.equals(s2)
3. int compareTo(String s)方法:按照字典序比较
与equals不同的是,equals返回的是boolean类型,而compareTo返回的是int类型,具体比较方式:
1. 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符大小的差值
2. 如果前k个字符相等(k为两个字符长度最小值),返回两个字符串长度差值。
String s1 = new String("abc");
String s2 = new String("abc");
String s3 = new String("abcdef");
String s4 = new String("ac");
System.out.println(s1.compareTo(s2)); //输出结果0
System.out.println(s1.compareTo(s3)); //输出结果-3
System.out.println(s1.compareTo(s4)); //输出结果-1
4.int compareToIgnorCase(String str)方法:与compareTo方式相同,但是忽略大小写比较
String s1 = new String("abc");
String s2 = new String("ABC");
String s3 = new String("aBcDe");
System.out.println(s1.compareToIgnoreCase(s2)); //输出结果为0
System.out.println(s2.compareToIgnoreCase(s3)); //输出结果为-2
2.3 字符串查找
字符串查找也是字符串中重要的操作,String类提供常用查找的方法
方法 | 功能 | char charAt(int index) | 返回index位置字符 | 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 static void main(String[] args) {
String s = "aabbccddccbbaa";
System.out.println(s.charAt(2)); //b
System.out.println(s.indexOf('c')); //4
System.out.println(s.indexOf("dd")); //6
System.out.println(s.indexOf('c',3)); //4
System.out.println(s.indexOf("bb",5)); //10
System.out.println(s.lastIndexOf('c')); //9
System.out.println(s.lastIndexOf("bb")); //10
System.out.println(s.lastIndexOf('b',5)); //3
System.out.println(s.lastIndexOf("bb",6)); //2
}
注意:上述方法都是实例方法
2.4 转化
1.数值和字符串转化
//数字转字符串
String s1 = String.valueOf(20);
String s2 = String.valueOf(3.14);
String s3 = String.valueOf(true);
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
//字符串转数字
int a = Integer.parseInt("20");
double b = Double.parseDouble("3.14"); //Integer Double 都是包装类
System.out.println(a);
System.out.println(b);
2. 大小写转换
/大小写转换 ? ? ? ? String s1 = "HELLO"; ? ? ? ? String s2 = "hello"; ? ? ? ? System.out.println(s1.toLowerCase()); //转小写 ? ? ? ? System.out.println(s2.toUpperCase()); //转大写
//输出结果: hello HELLO ?
?3. 字符串与数组相互转换
//字符串转数组
String s = "hello";
char[] ch = s.toCharArray();
for(int i=0;i<ch.length;i++){
System.out.println(ch[i]);
}
System.out.println();
//数组转字符串
String s2 = new String(ch);
System.out.println(s2);
4. 格式化
String s = String.format("%d-%d-%d",2021,10,29);
System.out.println(s); //2021-10-29
?2.5 字符串的不可变性
String是一种不可变的对象,字符串中的内容是不可改变的,字符换不可被修改,是因为:
1. String类在设计时就是不可改变的,String类实现描述中已经说明了

?String类中的字符实际保存在内部维护的value字符数组中,该图还可以看出:
1.String类被final修饰,表示该类不能被继承
2. value被final修饰,表明value自身的值不能改变,即不能引用其他字符数组,但是引用空间中的内容可以修改
2. 所有涉及到可能修改字符串内容的操作都是在创建一个新对象,改变的是新对象
final修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内容可以修改
为什么String要设计成不可变的? 1. 方便实现字符串对象池,如果String可变,那么对象池就需要考虑何时深拷贝字符串的问题。
2. 不可变对象是线程安全的
3. 不可变对象更方便缓存hash code,作为key时可以更高效的保存到HashMap中。
2.6 字符串修改
注意:尽量避免直接对String类型对象进行修改,因为String类是不能修改的,所有的修改都会创建新对象,效率非常低下。
public static void main(String[] args) {
String s = "hello";
s += "world";
System.out.println(s);
}
这种方式效率非常低,不推荐使用,中间创建了好多临时对象
3. StringBuilder和StringBuffer
3.1 StringBuilder的介绍
由于String的不可更改特性,为了方便字符串的修改,Java中提供了StringBuilder和StringBuffer类,这两个类大部分功能是相同的,这里介绍StringBuilder常用的一些方法。
方法 | 说明 | StringBuilder() | 构造一个空的字符串构建器 | int length() | 返回构建器中代码单元的数量 | StringBuilder append(String str) | 追加一个字符串 | StringBuilder append(char c) | 追加一个代码单元 | void setCharAt(int i,char c) | 将第i个代码单元设置为c | StringBuilder insert(int offset,String str) | 在offset位置插入一个字符串 | StringBuilder insert(int offset,char c) | 在offset位置插入一个代码单元 | StringBuilder delete(int starIndex,int endIndex) | 删除偏移量从starIndex到endIndex-1的代码单元 | StringBuilder reverse() | 反转字符串 | String toString() | 将所有字符按照String方式返回 | String substring(int start) | 从start开始一直到末尾的字符以String的方式返回 |
public static void main(String[] args) {
StringBuilder s = new StringBuilder("hello");
s.append(' ');
s.append("world");
System.out.println(s);
System.out.println(s.length());
s.insert(6,"and");
System.out.println(s);
s.reverse();
System.out.println(s);
System.out.println(s.substring(5));
System.out.println(s.toString());
}
执行结果:
hello world
11
hello andworld
dlrowdna olleh
dna olleh
dlrowdna olleh
注意:String和StringBuilder类不能直接转换,要转换,采用以下原则:
· String变为StringBuilder,利用StringBuilder的构造方法或append()方法
· StringBuilder变为String,调用toString()方法
3.2 区别
· String的内容不可修改,StringBuffer与StringBuilder的内容可以修改
· StringBuffer与StringBuilder大部分功能是相似的
· StringBuffer采用同步处理,属于线程安全操作;StringBuilder未采用同步处理,属于线程不安全操作
?
?
?
?
?
|