标签:unsigned 插入数据 列表 应该 shm 算法 父类 str oba
Object是Java中所有类的父类,对它的学习十分的重要, Object的函数除了final方法,基本上都是被设计为要被覆盖的(Override),这节我们就一起来学习这些函数。
/*equals的源代码*/
public boolean equals(Object obj) { return (this == obj); }
从源代码中我们可以看出来,不重写equals函数的话,一个对象只会与它本身相等,因此对于"值类"(String、Integer等)我们往往需要覆盖其equals函数。
Java中有如下的"约定"
equals()返回true------------------->hashCode()值相等//这个也是覆盖equals函数必须覆盖hashCode函数的原因之一
hashCode值相同------推不出--------equals()结果
a==b --------------------->equals()值为true
instanceOf返回false------------------>equals()值为false
final class PhoneNumber{
private final int areaCode;
private final int prefix;
private final int lineNumber;
public PhoneNumber(int areaCode,int prefix,int lineNumber){
this.areaCode=areaCode;
this.prefix=prefix;
this.lineNumber=lineNumber;
}
@Override
public boolean equals(Object obj){
if(obj==this) return true;
if(!(obj instanceof PhoneNumber)) return false;
PhoneNumber o=(PhoneNumber) obj;
return o.lineNumber==this.lineNumber
&&o.prefix==this.prefix
&&o.areaCode==this.areaCode;
}
}
main 函数
public static void main(String[] args) {
Map<PhoneNumber,String> map=new HashMap<>();
map.put(new PhoneNumber(1,2,10),"AAA");
map.put(new PhoneNumber(4,6,20),"BBB");
System.out.println(new PhoneNumber(1,2,10).equals(new PhoneNumber(1,2,10)));
System.out.println(new PhoneNumber(1,2,10).hashCode()==new PhoneNumber(1,2,10).hashCode());
System.out.println(map.get(new PhoneNumber(1,2,10)));
}
这段代码有三个输出流,而且PhoneNumber类并没有覆盖hashCode函数
1.验证equals函数,输出true,可以看出没有覆盖hashCode函数对equals没有什么影响
2.验证hashCode函数,由于没有覆盖HashCode函数,调用的是Object类的hashCode函数,两个类就算值是相同的,hashCode值也是不一样的,输出为false
3.Map中插入了一条数据key:new PhoneNumber(1,2,10) value:AAA,但是使用get函数的时候却找不到这个值了(输出null),这是因为没有遵循java中重写equals不重写hashCode函数的原因。
具体的原因:
图1.HashMap结构图
HahMap底层是一个数组Entry[],每个数组元素是一个单链表,插入数据和获取数据的过程基本如下(过滤掉细节)
a.插入数据过程
b.查找数据过程
1.遵循Java规范,覆盖equals()时应该覆盖hashCode()的值
2.覆盖hashCode之后输出结果改变
@Override public int hashCode(){ return this.areaCode^this.prefix^this.lineNumber; } //输出结果 true true AAA
/*Object 中的hashCode函数*/ public native int hashCode(); //是一个native函数,也就是不是用Java开发的
问题:它是怎么编写的?----先留着
@Override public int hashCode(){ return 1; }
static inline intptr_t get_next_hash(Thread * Self, oop obj) { intptr_t value = 0 ; if (hashCode == 0) { // This form uses an unguarded global Park-Miller RNG, // so it‘s possible for two threads to race and generate the same RNG. // On MP system we‘ll have lots of RW access to a global, so the // mechanism induces lots of coherency traffic. value = os::random() ; } else if (hashCode == 1) { // This variation has the property of being stable (idempotent) // between STW operations. This can be useful in some of the 1-0 // synchronization schemes. intptr_t addrBits = intptr_t(obj) >> 3 ; value = addrBits ^ (addrBits >> 5) ^ GVars.stwRandom ; } else if (hashCode == 2) { value = 1 ; // for sensitivity testing } else if (hashCode == 3) { value = ++GVars.hcSequence ; } else if (hashCode == 4) { value = intptr_t(obj) ; } else { // Marsaglia‘s xor-shift scheme with thread-specific state // This is probably the best overall implementation -- we‘ll // likely make this the default in future releases. unsigned t = Self->_hashStateX ; t ^= (t << 11) ; Self->_hashStateX = Self->_hashStateY ; Self->_hashStateY = Self->_hashStateZ ; Self->_hashStateZ = Self->_hashStateW ; unsigned v = Self->_hashStateW ; v = (v ^ (v >> 19)) ^ (t ^ (t >> 8)) ; Self->_hashStateW = v ; value = v ; } value &= markOopDesc::hash_mask; if (value == 0) value = 0xBAD ; assert (value != markOopDesc::no_hash, "invariant") ; TEVENT (hashCode: GENERATE) ; return value; }
标签:unsigned 插入数据 列表 应该 shm 算法 父类 str oba
原文地址:http://www.cnblogs.com/yangyunnb/p/6082633.html