JAVA1.8阅读String类源码心得体会
前几天在二面某大厂的时候被问到String类的问题,没有回答上来。所以回来恶补了一下String类的源码。确实阅读源码感受到了设计者代码的优雅和巧妙,在此记录一下自己印象比较深刻的心得体会。
- equals()
用来判断两个字符串是否相等,这里使用了很巧妙的判断逻辑,来尽量节省时间。首先判断待比较的对象是不是自己本身,然后判断和待比较对象是不是同一个类,然后又比较了待比较对象的长度是否和this对象相同。如果都不相同,再转化成char数组,逐个字符比较。 - hashcode()
hashcode里面比较关键的逻辑是hashcode的值的计算,这里使用了一个算子31。关于为什么取31有兴趣的朋友可以自行了解一下。大概有两个原因。1)31是个大小合适的质数,在进行hash算法的时候,不会造成太多的hash冲突,也不会占用太大的空间。2)h*31的操作可以转化为位运算。(h<<5)-h 可以提升计算速度。源码如下:
public int hashCode() {
int var1 = this.hash;
if (var1 == 0 && this.value.length > 0) {
char[] var2 = this.value;
for(int var3 = 0; var3 < this.value.length; ++var3) {
var1 = 31 * var1 + var2[var3];
}
this.hash = var1;
}
return var1;
}
- indexOf()
这个让方法让我有点意外的是,它有重载的方法可以接收ASCII码值,用来判断字符串中是否含有该ASCII码的下标。 - contains()
注意这个方法的参数类型是CharSequence
类型,这个让我意外的是,contains()方法,直接调用了indexOf()方法,很简洁。代码如下:
String mwz = "ABCDEF";
CharSequence c = "C";
System.out.println(mwz.contains(c));
- compareTo()
看源码发现,String类其实实现了Comparable<String>
接口,而该接口里面只有一个方法就是compareTo(),这个方法的实现,可以返回的是两个字符串的首字母的差值。(这个和想象的不太一样。 - startsWith()
可以接收两个参数,待比较内容和偏移量。startsWith()的设计也很巧妙,并不是我想象中上来就的无脑遍历数组。它首先比较的是 otherString.length+起始位置 ==thisString.length。 的长度。如果长度溢出了直接返回-1。 - contentEquals()
这个方法可以直接和StringBuffer和CharSequence类的对象比较内容。 - codePointAt()
返回的是地址下标的值的ACSCII的值。如,返回67
String mwz = "ABCDEF";
System.out.println(mwz.codePointAt(2));