String 源码分析
继承关系
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
final修饰的类 不可以被继承

CharSequence
CharSequence类是java.lang包下的一个接口,此接口对多种不同的对char访问的统一接口,像String、StringBuffer、StringBuilder类都是CharSequence的子接口;
CharSequence类和String类都可以定义字符串,但是String定义的字符串只能读,CharSequence定义的字符串是可读可写的;
对于抽象类或者接口来说不可以直接使用new的方式创建对象,但是可以直接给它赋值;
用法:
CharSequence a = “abc”; 等价于: CharSequence a = new String(“abc”);
底层数据结构
private final byte[] value;
底层是被final修饰的byte数组,说明String 对象不可被更改。Java 实现的这个特性叫作 String 对象的不可变性,即 String 对象一旦创建成功,就不能再对它进行改变。
常用构造器:
无参构造器
public String() {
this.value = "".value;
}
返回空字符串的数组形式。
入参为String类型
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
返回原来String对象的各个参数
入参为char数组类型
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
public String(char value[], int offset, int count) {
if (offset < 0) {
throw new StringIndexOutOfBoundsException(offset);
}
if (count <= 0) {
if (count < 0) {
throw new StringIndexOutOfBoundsException(count);
}
if (offset <= value.length) {
this.value = "".value;
return;
}
}
// Note: offset or count might be near -1>>>1.
if (offset > value.length - count) {
throw new StringIndexOutOfBoundsException(offset + count);
}
this.value = Arrays.copyOfRange(value, offset, offset+count);
}
Arrays.copyOf方法进行数组拷贝的
入参为StringBuffer:
public String(StringBuffer buffer) {
synchronized(buffer) {
this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
}
}
加锁进行拷贝,保证StringBuffer的线程安全
入参为StringBuilder:
public String(StringBuilder builder) {
this.value = Arrays.copyOf(builder.getValue(), builder.length());
}
对比StringBuffer入参,如果用StringBuilder作为入参是不加锁操作的,因为StringBuilder本身线程不安全,但会提升性能。
常用方法
int length()
public int length() {
return value.length;
}
语法:字符串变量名.length();
返回值为 int 类型。得到一个字符串的字符个数(中、英、空格、转义字符皆为字符,计入长度)
equals()
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
字符串内容比较
char charAt(int index);
语法 :字符串名.charAt(值);
返回值为 char 类型。从字符串中取出指定位置的字符
char toCharArray();
语法 :字符串名.toCharArray();
返回值为 char 数组类型。将字符串变成一个字符数组
int indexOf(char c)
语法 :字符串名.indexOf(“字符”);字符串名.indexOf(“字符”,值);
查找一个指定的字符串是否存在,返回的是字符串的位置,如果不存在,则返回-1 。
in lastIndexOf(char c)
得到指定内容最后一次出现的下标
toUpperCase(); toLowerCase();
字符串大小写的转换
split(char c)
根据给定的正则表达式的匹配来拆分此字符串。形成一个新的String数组。
trim()
去掉字符串左右空格
replace(char oldChar,char newChar)
新字符替换旧字符,也可以达到去空格的效果一种。
substring(int beginIndex,int endIndex)
截取字符串
equalsIgnoreCase(String)
忽略大小写的比较两个字符串的值是否一模一样,返回一个布尔值
contains(String)
判断一个字符串里面是否包含指定的内容,返回一个布尔值
String,StringBuffer与StringBuilder的区别
三者共同之处
都是final类,不允许被继承,主要是从性能和安全性上考虑的,因为这几个类都是经常被使用着,且考虑到防止其中的参数被参数修改影响到其他的应用。
各自的特点
StringBuffer是线程安全,可以不需要额外的同步用于多线程中;
StringBuilder是非同步,运行于多线程中就需要使用着单独同步处理,但是速度就比StringBuffer快多了;
StringBuffer与StringBuilder两者共同之处:可以通过append、indert进行字符串的操作。
String实现了三个接口:Serializable、Comparable、CarSequence
StringBuilder只实现了两个接口Serializable、CharSequence,相比之下String的实例可以通过compareTo方法进行比较,其他两个不可以。
主要区别:
运行速度
首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > String
String最慢的原因:String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。
线程安全
在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的
如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。
(一个线程访问一个对象中的synchronized(this)同步代码块时,其他试图访问该对象的线程将被阻塞)
各自适用场景
String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
本文深入分析了Java中的String、StringBuilder和StringBuffer类,详细讲解了它们的继承关系、底层数据结构、构造器以及常用方法。String是不可变对象,其内部由final byte数组构成,而StringBuilder和StringBuffer则提供了可变字符串的功能,其中StringBuffer线程安全。文章还对比了三者的性能和适用场景,指出在单线程环境下StringBuilder更快,多线程时推荐使用StringBuffer。
3271

被折叠的 条评论
为什么被折叠?



