1.String类
1.1.基本介绍
String
类的对象用于保存字符串(一组字符序列) ,将字符序列用双引号括起来就是字符串常量,如:"abc","你好"- 字符串中的字符使用Unicode字符编码,一个字符不管是字母还是汉字,都占两个字节(char)
1.2.创建String类的对象
- 方式一: 直接赋值(字面量):
String s = "Java";
先从字符串常量池中查看是否有"java"
的数据空间,如果有直接将value[]数组指向该数据空间的地址;如果没有则创建后指向;s -> value[] -> "java"在常量池中的地址
字符串常量池中不允许存放两个相同的字符串常量;
jdk7之前:字符串常量池在方法区中
jdk7及之后:字符串常量池在堆空间中
- 方式二:调用构造器:
//String类常用的构造方法(体现了方法的重载)
String s = new String();//String()
String s1 = new String("Hello");//String(String original)
char[] c = {'j','a','v','a'};
String s2 = new String(c); //String(char value[])
String s3 = new String(c, 0, 3);//String(char value[], int offset, int count)
输出后:
以String s = new String("Java");
为例:
先在堆中创建空间,里面有String
类用于存放字符串属性(value[]
数组),s 指向 value[]
的地址;常量池中如果有"Java"
,则直接通过value[]
指向其地址,没有则重新创建后再指向。
注意:s最终指向的是堆中value[]
的地址空间(区别与第一种方式)
1.3.String类细节
String
类是final
类,代表不可变的字符序列,不能被其他类继承
-
String
类实际上是利用属性private final char value[]
这个字符类型数组来存放字符串- jdk9之后,为了节省内存空间,使用
private final byte[] value
作为存储字符串数据的容器
- jdk9之后,为了节省内存空间,使用
-
String
类重写了equals
方法,用于判断字符串内容是否相同 -
String
类相加重要规则: 如果是常量相加,看的是常量池,如果是变量相加,则看的是堆。-
常量 + 常量 :结果仍在常量池;此时的常量可能是
final
修饰常量 + 变量 / 变量 + 变量 :会在堆中new一个String对象返回其地址
调用
intern()
方法返回字符串常量池中字面量的地址 -
执行代码
String s = "Hello" + "Java";
时,编译器会判断创建的常量池对象是否有引用指向,所以只会创建一个"HelloJava"
对象,"Hello"
和"Java"
对象会被丢弃 -
String变量相加如下面代码
-
String a = "Hello";
String b = "Java";
String c = a + b;
则会创建Hello
、Java
和HelloJava
三个常量对象
- 不可变性的理解:
- 当对字符串变量重新赋值时,需要重新指定一个字符串常量的位置(新的常量池地址),不能在原有位置修改,原字符串常量仍存在
- 当对原有字符串进行拼接或者
replace()
操作时,都需要重新开辟空间保存新的字符串,原有字符串不能修改
1.4.String类的常用方法
equals
区分大小写判断内容是否相等equalsIgnoreCase
忽略大小写判断内容是否相等length
获取字符串的长度indexOf
获取指定字符或子串在字符串中第一次出现的索引,找不到返回-1lastIndexOf
获取指定字符在字符串中最后一次出现的索引,找不到返回-1substring
截取指定范围的子串
public static void main(String[] args) {
String s = "Hello,Java~";
System.out.println(s.substring(5));//从索引5开始截取后面的所有内容
System.out.println(s.substring(0,5));//从索引0开始截取长度为5的子串
}
trim
去除前后空格charAt
获取指定索引处的字符toUpperCase
转换成大写toLowerCase
转换成小写concat
拼接字符串replace
替换字符串中的字符split
根据指定的字符分割字符串(可以赋给一个数组)(分割时如果有特殊字符需加入转义字符)toCharArray
转换成字符串数组compareTo
逐位比较两字符串大小,前者大返回整数,后者大返回负数,相等返回零format
格式化字符串
2.StringBuffer
2.1.基本介绍
StringBugger
代表可变的字符序列,可以对字符串内容进行增删,很多方法和String
类相同,但StringBuffer
的长度是可变的。StringBuffer
同时也是一个容器。
2.2.创建StringBuffer对象
//创建一个容量为16的字符串缓冲区(char[]数组)存放字符串
StringBuffer sb = new StringBuffer();
//将参数中的字符串存入缓冲区,容量为当前字符串长度加16
StringBuffer sb1= new StringBuffer("Java");
//创建指定容量大小的字符串缓冲区
StringBuffer sb2 = new StringBUffer(100);
2.3.StringBuffer细节
StringBuffer
继承了父类AbstractStringBuffer
的属性char[] value
(不是final
的),所以字符串中的内容是存放在堆中的(value
指向堆中的字符数组地址)StringBuffer
是一个final
类,不能被继承- 扩容机制,默认创建新的容量为:原容量 * 2 + 2 的数组,将原有value数组中的元素复制到新数组
2.4.StringBuffer常用方法
append
增加字符delete(start,end)
按索引删除字符replace(start,end,string)
用string替换索引范围的子串indexOf(string)
查找子串在字符串第一次出现的索引,找不到返回-1insert(int,string)
在索引处插入指定字符串length
获取长度
2.5.String 对比 StringBuffer
String
保存的是字符常量,里面的值不能更改,String
类的对象每次更新都是更改地址(创建新对象) ,效率较低。StringBuffer
保存的是字符串变量,里面的值可以更改,每次更新时可以直接改变值,不用更新地址。
2.6.String和StringBuffer的转换
String
->StringBuffer
String str = "Java~";
//方式1 使用构造器
StringBuffer sb = new StringBuffer(str);
//方式2 使用append方法
StringBuffer sb1 = new StringBuffer();
sb1 = sb1.append(str);
StirngBuffer
->String
StringBuffer sb2 = new StringBuffer("Java~");
//方式2 使用构造器
String s = new String(sb2);
//方式1 使用StringBuffer的toString方法
String s1 = sb2.toString();
3.StringBuilder
3.1.基本介绍
StringBuilder
也是一个可变的字符序列,在字符串缓冲区被单个线程使用,可以作为一个简易的StringBuffer
。大多情况下StringBuilder
比StringBuffer
快,所以建议优先使用StringBuilder
。但此类有线程安全问题,使用时需注意。
3.2.StringBuilder主要方法
StringBuilder
和StringBuffer
方法是一样的。主要使用append
和insert
方法,可以重载这些方法用来接收任意类型的数据。
3.3.StringBuilder细节
StringBuilder
是final
类,不能被继承StringBuilder
也继承了父类AbstractStringBuilder
的属性char[] value
来存放数据,所以字符序列也在堆中。StringBuilder
的方法都没有做互斥的处理(synchronized关键字),所以在单线程的情况下才使用
4.三者对比
String | 不可变字符序列 | 效率低,但是复用率高(一个字符串可以被无限使用) |
---|---|---|
StringBuffer | 可变字符序列 | 效率高,线程安全 |
StringBuilder | 可变字符序列 | 效率最高,线程不安全 |
String
类如果多次执行改变串内容的操作,会导致大量没有引用字符串对象留在常量池中,降低效率;所以要对字符串做大量修改时,使用StringBuilder
(单线程时优先选择)和StringBuffer
,不使用String
- 在字符串对象无需频繁修改,被多个对象引用时,使用
String
效率更高。