目录
一、字符序列
多个字符按照一定的顺序组成的列表就叫作字符序列,字符串 java.lang.String 可以用来表示多个字符,用 "" 引
起来。字符串是引用数据类型,默认值是 null 。
JDK13 新增文本块(预览),在 JDK15 正式在字符串支持文本块,用 """ 表示
-
String 字符串
-
StringBuffer 字符串缓冲区,是线程安全的
-
StringBuilder 字符串构造器,非线程安全的
-
CharBuffer 字符缓冲区
以上都实现了 CharSequence 接口
二、字符串特性(不可变)
public final class String 是用 final 修饰的类,在 Java 中用 final 修饰的类不能被继承,也就是说 String 没有子类。
在 Java 中,关键字 final 表示最终的。可以用来修饰类、方法、变量。
-
被 final 修饰的类,不能被继承
-
被 final 修饰的方法,不能被重写
-
被 final 修饰的变量,不能变。如果是基本数据类型不能重新赋值,如果是引用数据类型不能改变引用。
从中我们发现,不管是 jdk 8 及以前还是 jdk 9 及以后版本, value 属性都是 final 的。就说明,字符串一旦声明就不
可变。所以字符串拥有不可变性。
为什么要这么改呢?
主要是为了节约 String 占用的内存,占用内存少引发另外一个好处就是减少 GC 次数。
众所周知,在大多数 Java 程序的堆里, String 占用的空间最大,并且绝大多数 String只有 Latin-1 字符,这些
Latin-1 字符只需要1个字节就够了。 JDK9 之前, JVM 因为 String 使用 char 数组存储,每个 char 占2个字节,所
以即使字符串只需要1字节/字符,它也要按照2字节/字符进行分配,浪费了一半的内存空间。
初始化新创建的 String对象,使其表示空字符序列
JDK9 是怎么解决这个问题的呢?一个字符串出来的时候判断,它是不是只有 Latin-1 字
符,如果是,就按照1字节/字符的规格进行分配内存,如果不是,就按照2字节/字符的规
格进行分配( UTF-16 编码),提高了内存使用率。
为什么用 UTF-16 而不用 UTF-8 呢,这就要从这两个字符集的设计说起了。
UTF-8 实际上是对空间利用效率最高的编码集,它是不定长的,可以最大限度利用内存和网络。但是这种编码集只
能用于传输和存储,并不适合拿来做 String 的底层实现。因为 String 有随机访问的方法,所谓随机访问,就是
charAt 、 subString 这种方法。如果字符串中的每个字符占用的内存是不定长的,那么进行随机访问的时候,就需
要从头开始数每个字符的长度,才能找到你想要的字符。
使用 UTF-16 编码将它们表示并存储为每个字符2个字节。
对于 JDK9 和更高版本,默认情况下,如果 String 的行为已更改为对字符串使用紧凑表示形式。
三、String常用方法
1.构造方法
方法名 | 描述 |
---|---|
String() | 初始化新创建的 String对象,使其表示空字符序列 |
String(byte[] bytes) | 通过使用平台的默认字符集解码指定的字节数组来构造新的 String |
String(byte[] bytes, Charset charset) | 构造一个新的String用指定的字节的数组解码charset |
String(byte[] bytes, String charsetName) | 构造一个新的String用指定的字节的数组解码charsetName |
String(char[] value) | 构造一个新的String由指定的字符的数组构成 |
String(String original) | 初始化新创建的String对象,使其表示与参数相同的字符序列; 换句话说,新创建的字符串是参数字符串的副本 |
String(StringBuffer buffer) | 分配一个新的字符串,其中包含当前包含在字符串缓冲区参数中的字符序列 |
String(StringBuilder builder) | 分配一个新的字符串,其中包含当前包含在字符串构建器参数中的字符序列 |
2.实例方法
方法名 | 返回值 | 描述 |
---|---|---|
charAt(int index) | char | 返回指定索引处的字符 |
codePointAt(int index) | int | 返回指定索引处的字符(Unicode代码点)。 |
compareTo(String anotherString) | int | 按字典顺序比较两个字符串 |
compareToIgnoreCase(String str) | int | 按字典顺序比较两个字符串,忽略大小写 |
concat(String str) | String | 将指定的字符串连接到该字符串的末尾 |
contains(CharSequence s) | boolean | 当且仅当此字符串包含指定的s值序列时才返回true |
endsWith(String suffix) | boolean | 测试此字符串是否以指定的后缀结尾 |
startsWith(String prefix) | boolean | 测试此字符串是否以指定的前缀开头 |
equals(Object) | boolean | 比较字符串 |
四、isEmpty 和 isBlank 区别
isEmpty 当且仅当字符串长度为0时返回 true
isBlank 当字符串长度为0或字符串中全是空白字符时都是 true