String其实就是一个char集合
String只是大致看了下,基本都是对char数组的操作,包括判断是否为空,或者取指定下标数据等等。。
String类是final修饰的,所以不可被继承,实现了java.io.Serializable, Comparable
主要记录下equals和hashCode两个方法,这两个方法都是重写的Object类的。
Object类的equals方法其实使用的还是"=="
public boolean equals(Object obj) {
return (this == obj);
}
而hashCode不是用java写的,就不多说了
下面是String重写的
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;
}
首先判断对象地址是否相同,地址相同就直接返回true,地址不相同再判断字符串长度是否相同,最后再对字符串的每个字符一一进行对比。
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
可以举个例子:
当前字符集是ASCII
System.out.println("a".hashCode());//97 对应的是ASCII码表a的十进制数
System.out.println("b".hashCode());//98 对应的是ASCII码表a的十进制数
System.out.println("ab".hashCode());//3105 根据h=31*h+val[i]来算 第一遍循环hash=0,也就是h=0,第一遍循环走完h='a', 第二遍循环其实就是'a'*31+'b'=3105
哈希的地址算法主要就是h = 31 * h + val[i],每次是将上次一算出的hash值乘以31 然后再加上当前字符编码值,由于这里使用的是int肯定会有一个上限,当字符串超过上限,HashCode的正确性就无法保证了,所以这点可以推断出HashCode存在不相同字符拥有相同HashCode。
字符串相同,哈希一定相同,哈希相同,字符串不一定相同。
String的hashcode计算为什么选择31这个质数来计算,主要是是因为31 * i = (i << 5) - i,这样JVM使用位运算速度更快,而且冲突率也会比较小。
参考https://www.cnblogs.com/nullllun/p/8350178.html