java源码阅读笔记-String
1 String方法
1.1 构造方法
// String 为参数的构造方法
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
// char[] 为参数构造方法
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
// StringBuffer 为参数的构造方法
public String(StringBuffer buffer) {
synchronized(buffer) {
this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
}
}
// StringBuilder 为参数的构造方法
public String(StringBuilder builder) {
this.value = Arrays.copyOf(builder.getValue(), builder.length());
}
1.2 equals()方法源码
public boolean equals(Object anObject) {
// 对象引用相同直接返回 true
if (this == anObject) {
return true;
}
// 判断需要对比的值是否为 String 类型,如果不是则直接返回 false
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
// 把两个字符串都转换为 char 数组对比
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
// 循环比对两个字符串的每一个字符
while (n-- != 0) {
// 如果其中有一个字符不相等就 true false,否则继续对比
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
Object类的equeals()源码
public boolean equals(Object obj) {
//对于基本数据类型来说,是用于比较 “值”是否相等的;而对于引用类型来说,是用于比较引用地址是否相同的。
return (this == obj);
}
1.3 compareTo() 比较两个字符串
-
如果指定的数与参数相等,返回0
如果指定的数小于参数,返回数值小于0,为负数
如果指定的数大于参数,返回数值大于0,为正数
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
// 获取到两个字符串长度最短的那个 int 值
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
// 对比每一个字符
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
// 有字符不相等就返回差值
return c1 - c2;
}
k++;
}
//如果取出最短的字符串与长字符串中部分完全相等,返回长度之差,字符长度大的大
return len1 - len2;
}
1.4 indexOf():查询字符串首次出现的下标位置
public int indexOf(int ch, int fromIndex) {
//获取字符串的长度设为最大长度
final int max = value.length;
//开始查询的下标位置为负数则默认为0
if (fromIndex < 0) {
fromIndex = 0;
} else if (fromIndex >= max) {
//开始查询的位置大于等于字符串长度最大值,直接返回-1,因为下标从0开始
return -1;
}
//Character.MIN_SUPPLEMENTARY_CODE_POINT是指字符是小于两个字节的
if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
final char[] value = this.value;
for (int i = fromIndex; i < max; i++) {
if (value[i] == ch) {
return i;
}
}
return -1;
} else {
return indexOfSupplementary(ch, fromIndex);
}
}
private int indexOfSupplementary(int ch, int fromIndex) {
if (Character.isValidCodePoint(ch)) {
final char[] value = this.value;
final char hi = Character.highSurrogate(ch);
final char lo = Character.lowSurrogate(ch);
final int max = value.length - 1;
for (int i = fromIndex; i < max; i++) {
if (value[i] == hi && value[i + 1] == lo) {
return i;
}
}
}
return -1;
}
1.5 其他常用函数
contains():查询字符串中是否包含另一个字符串,底层使用的是indexof()
length():查询字符串的长度
trim():去掉字符串首尾空格
replace():替换字符串中的某些字符
split():把字符串分割并返回字符串数组
join():把字符串数组转为字符串
1.6 == 和 equals 的区别
== 对于基本数据类型来说,是用于比较 “值”是否相等的;而对于引用类型来说,是用于比较引用地址是否相同的。
1.7 String常见创建方式解释
String 常见的创建方式有两种,new String() 的方式和直接赋值的方式,直接赋值的方式会先去字符串常量池中查找是否已经有此值,如果有则把引用地址直接指向此值,否则会先在常量池中创建,然后再把引用指向此值;而 new String() 的方式一定会先在堆上创建一个字符串对象,然后再去常量池中查询此字符串的值是否已经存在,如果不存在会先在常量池中创建此字符串,然后把引用的值指向此字符串。