对于字符串的相关处理操作是应用程序最常见、最常用的场景了,对于java语言来讲,语言没有提供内置的字符串类型,而是通过boolean、byte、short、char、int、long、float、double八种基础类型中的char字符一系列定义操作来抽象字符串的一系列的定义和操作处理。
所以字符串的类类型实现都是基于char类型的存储结构,基本上都是采用char[]字符数组作为字符串的存储结构。那么对于字符串的定义和处理,一种是可以采用语言内置的char类型来自定义封装字符串类及操作实现,另一种是JDK作为java的标准类库提供了统一的字符串类类型,可以直接使用。
JDK中对字符串类型的定义和相关处理能力主要有String、StringBuffer、Stringbuilder三个主要的类,位于JDK的lang包中。这三个实现类总结可以归类为两类:
1)一类是不可变字符串类类型,标准String字符串类就是这一类的,因其中存储具体字符串数据结构的char[]字符数组是final不可修改类型的,任何对赋值之后的字符串修改都无法在原先的字符数组中完成变更;
2)一类是可变字符串类类型,StringBuffer、Stringbuilder字符串类就是这一类,因其中存储的字符串数据结构的char[]字符数组是可被修改类型的,任何对赋值之后的字符串修改都可以反映在该字符数组的变更操作上;
这里我们不妨来猜测一下JDK在提供这几个类封装时候的思路:从类注解的版本信息来分析
1. 先在JDK1.0时候定义了String作为主字符串类封装主体,同时StringBuffer作为字符串辅助类也在1.0版本出现了;
2. 之后StringBuffer逐步演变为支持同步操作的可变字符串类类型,看很多支持同步的方法都是1.5版本才出现的,应该是逐步演进中找到了类的定位;
3. 1.5版本新增了StringBuilder可变字符串类类型,主要归类封装了非同步操作的字符串。
这三个相关类的基本关系如下,JDK为了统一接口和实现可扩展,为这三个实现类定义统一的接口和抽象类层次结构:
1.统一的字符序列接口类CharSequence
所有字符串基本组成单位都是char字符,CharSequence该类是一个字符序列接口类,该接口类定义基于字符序列串的一系列接口标准。接口类中没有具体的数据结构定义,一般在实现的具体字符串相关类中基于字符串结构定义实现相关CharSequence接口。
标准接口定义如下:
CharSequence接口类规约了字符序列基本的接口,后续的具体基于字符序列的字符串实现类大多在此基础上实现接口或者扩充它们的功能。
2.非可变标准字符串类String
JDK为字符串的操作处理定义了专门的字符串类类型,该类主要实现了字符序列的接口类CharSequence,同时定义了字符串处理的基本结构,另外扩充了字符串上的更丰富的操作方法。
String字符串类是个非常庞大的字符串实现类,该类基本构成如下:
1)类的声明定义
标准字符串类String实现三个接口类
a. String类定义为final类型,禁止被继承
b. 实现了java.io.Serializable序列化的接口类,标识可以被序列化
c. 实现了Comparable对象比较接口类,支持字符串对象的compareTo(T o)比较功能
d. 实现了统一的字符可读序列接口类,支持字符一系列操作功能定义
public final class String
implements java.io.Serializable, Comparable, CharSequence
2)数据结构的定义
a. 字符串存储的主体,字符数组。字符串是一连续的字符类型数据组成的,该字符串数据结构在String类中由一个字符数组组成,定义结构如下(String类中基本上所有字符串的创建、操作方法都是围绕该value字符数组展开的,由于该字符串实现类的方法众多,这里就不一一展开说明。):
private final char value[];
b. 可序列化字段数组,该结构主要用于存放字符串对象中可序列化的部分。
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[0];
3)字符串相关操作
字符串处理的操作方法众多,是个比较庞大的类。该类的方法简单归类后如下:
a. 字符串对象构造方法,主要用于构建标准字符串操作的对象。
b. 字符串处理操作方法,具体比较多后续会归类列举,看看关键方法源码实现思路。
3.统一抽象可变字符串类AbstractStringBuilder
与标准字符串String不同的是AbstractStringBuilder是一个可被修改的字符串类型的抽象类定义,该抽象类使用可被修改的字符数组结构表示字符串的存储结构。同时该类派生了两个具体的可变字符串操作类StringBuilder和StringBuffer。
1)类的声明定义
抽象可变字符串处理类AbstractStringBuilder实现两个接口类
a. AbstractStringBuilder类型为abstract抽象类;
b. 实现了Appendable接口类,支持实现该接口的字符串操作类能够被append追加char序列跟值;
c. 实现了CharSequence字符可读序列接口类,支持字符一系列操作功能定义
abstract class AbstractStringBuilder implements Appendable, CharSequence
2)数据结构的定义
抽象的可变字符串AbstractStringBuilder类定义了可变字符串数据结构,该结构跟之前标准String字符串类不同的是字符数组value是可变的,另外还定义了count变量用于计数数组中已经被使用的字符个数,该结构定义如下:
char[] value;
int count;
3)抽象字符串处理类AbstractStringBuilder方法定义
该类方法也比较多,基本上都是常规的可变字符串操作方法,主要包括如下几类:
a. 可变字符串操作类构造方法,主要构造可变字符串操作类对象,这里因为是抽象类,因此不允许被实例化;
b. 字符串处理操作方法,具体都是基于char [] value字符串数组的操作;
4.可变字符串操作类StringBuilder(线程非安全)
StringBuilder实现类继承至统一的抽象类AbstractStringBuilder,作为可变字符串操作具体实现类,该类是线程非安全的,即该类不考虑字符串并发操作下的控制,性能会好一些,绝大部分情况下字符串的操作基本上都是线程非安全的。
1)类的声明定义
可变字符串操作实现类StringBuilder关系如下。
a. 继承至统一的统一抽象可变字符串类AbstractStringBuilder,继承了该抽象类的相关操作方法和数据结构定义;
b. 实现了序列化接口和字符序列接口类CharSequence。
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
2)数据结构定义
该类的数据结构继承至统一抽象可变字符串类AbstractStringBuilder,该可变字符串操作实现类都基于同一的字符数组数据结构作为字符串存储主体。
char[] value;
3)操作方法定义
该类方法也比较多,基本上都是实现统一抽象类中可变字符串操作方法,主要包括如下几类:
可变字符串操作实现类构造方法,主要构造可变字符串操作类对象,这里StringBuilder是实现类,所以可以被实例化对象;
字符串处理具体实现操作方法,都是基于char [] value字符串数组的操作;
5.可变字符串操作类StringBuffer(线程安全)
StringBuffer实现类继承至统一的抽象类AbstractStringBuilder,作为可变字符串操作具体实现类,该类是线程安全的,即该类考虑字符串并发操作下的控制,因为涉及并发控制性能略为差些,大多在有并发控制场景使用,确保操作字符串修改是安全的。
1)类的声明定义
可变字符串操作实现类StringBuffer关系如下。
a. 继承至统一的统一抽象可变字符串类AbstractStringBuilder,继承了该抽象类的相关操作方法和数据结构定义;
b. 实现了序列化接口和字符序列接口类CharSequence。
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
2)数据结构定义
该类的数据结构继承至统一抽象可变字符串类AbstractStringBuilder,该可变字符串操作实现类都基于同一的字符数组数据结构作为字符串存储主体。
char[] value;
3)操作方法定义
该类方法也比较多,基本上都是实现统一抽象类中可变字符串操作方法,主要包括如下几类:
a. 可变字符串操作实现类构造方法,主要构造可变字符串操作类对象,这里StringBuffer是实现类,所以可以被实例化对象;
b. 字符串处理具体实现操作方法,都是基于char [] value字符串数组的操作;