本文基于java8
String 类的源码极其简单,本质上是对内部数组的操作,但内部重载方法比较多,建议自己直接阅读源码。
类定义
String 类被设计为 final ,这意味着它不能被继承。
接口
该类实现了三个接口:
- java.io.Serializable :不含任何方法,标识该类可以进行序列化
- Comparable
: 包含 compareTo(T o) ;用于对象比较 - CharSequence :包含 length() , charAt(int) , subSequence(int,int),toString() ;表示char值的一个可读序列
方法
String类包括用于检查序列的各个字符的方法:
- 比较字符串
- 搜索字符串
- 提取子字符串
- 创建将所有字符翻译为大写或小写的字符串的副本
存储结构
该类的存储结构是一个不可变的 char 数组,String 类的对象创建后就不能进行修改。 JDK 提供了两个类用于构造可变的字符串: StringBuilder(线程不安全)、StringBuffer(线程安全)。
属性
private final char[] value;
用于存储 String 的实际内容,定义为 final,不可修改。
private int hash;
hashCode() 的缓存。对象求 hashCode 时,会通过该属性判断是否进行过 hashCode 操作,如果有缓存直接返回,否则计算 hashCode 后将其存储到该属性中。
public static final Comparator CASE_INSENSITIVE_ORDER
指向静态内部类,用于忽略大小写比较字符串。
构造器
前面说过,String 的存储结构是一个 Char 数组,基于此,String 类的所有构造方法本质上都是对该数组赋值。 其构造参数主要接受 byte[] 、 char[] 、 int[] 、 String 、StringBuffer 、StringBuilder 六种类型参数。
byte[]使用字节构造字符串
参数:
- byte[]
可选参数
- 起始位置,复制个数 (int ,int)
- 编码 Charset 或 String
char[]使用字符构造字符串
参数:
- char[]
可选参数
- 起始位置,复制个数 ( int , int)
int[]使用码点构造字符串
参数:
- 码点 int[]
- 起始位置,复制个数 ( int , int )
String等
初始化新创建的String对象,使其表示与参数相同的字符序列; 换句话说,新创建的字符串是参数字符串的副本。
方法
接口方法
Comparable 接口
compareTo(String other) 方法
依次比较两个字符串中的字符,遇到字符不同时返回 对象在该字符位置与other的差值,所有字符相同,返回长度差值。 返回 0 为两个字符相同
CharSequence 接口
charAt(int index)
返回指定位置的字符
length()
返回字符串长度
subSequence(int beginIndex, int endIndex)
返回指定范围的字符串子串
toString()
略
因为String类内部方法大多是重载方法,逻辑大致相同参数不同,故将逻辑功能相同的方法统一分析
其他方法
codePoint*
代码点方法:用于返回指定位置、指定位置之前的代码点及两个位置之间代码点个数
compareTo*
字符串比较方法(可忽略大小写):依次比较两个字符串中的字符,遇到字符不同时返回 对象在该字符位置与other的差值,所有字符相同,返回长度差值。 返回 0 为两个字符相同
contentEquals、nonSyncContentEquals
判断两个字符串内容是否相等(可忽略大小写);多线程环境必须使用contentEquals
indexOf、lastIndexOf
字符串搜索方法:返回指定字符第一次或最后一次出现的索引
字符串编辑方法
format()
使用转换符(类似C语言的 %d )等对字符串进行格式化,非常不常用。
trim()
去除字符串两端的空格
concat(String other)
将other拼接到当前字符换后边;相当于 str1 + str2
replace*
将字符串中第一个字符、字符串、所有字符串替换为指定字符、字符串
toLowerCase、toUpperCase
返回当前字符串的大写小写格式(可指定编码)
substring
返回字符串截取出的字串
判断字符串
contains(String other)
判断字符串时候包含指定字符串
startWith,endsWith
判断字符串是否以指定字符串开始、结束(判断前缀时可指定判断起始位置)
matches
判断字符串是否匹配正则
get* 、toCharArray
将该对象的 char[] 复制到 byte[](可指定编码) 、 char[] 中,或返回字符数组。
join (CharSequence delimiter, CharSequence… elements)
使用指定字符串 delimiter 对 多个 elements 进行连接
split
将字符串以指定规则分割为字符数组,可指定分割次数
intern()
本地方法,一般面试中会有题目 用来返回常量池中的某字符串,如果常量池中已经存在该字符串,则直接返回常量池中该对象的引用。否则,在常量池中加入该对象,然后 返回引用。 字符串有两种情况进入常量池:
- 使用”“包裹的字符串会进入常量池
- 在字符串上调用 intern()
copyValueOf、 valueOf
返回使用基本数据类型构造的字符串
hashCode 方法
该方法使用属性 hash 字段对 hashCode 进行了缓存,提高了效率。
equals*
判断两个 String类的实例 内容是否相同
资料
Java– String源码分析
为什么 String hashCode 方法选择数字31作为乘子
忽略大小写比较器 CaseInsensitiveComparator 为什么比较大写还要比较小写