2019-08-12 13:55:44 4561浏览
今天千锋扣丁学堂Java培训老师给大家分享一篇关于Java中HashCode方法的相关资料,文中通过示例代码介绍的非常详细,下面我们一起来看一下吧。
package main import "fmt" func main() { var a int= 20 /* 声明实际变量 */ var ip *int /* 声明指针变量 */ ip = &a /* 指针变量的存储地址 */ fmt.Printf("a 变量的地址是: %x\n", &a ) /* 指针变量的存储地址 */ fmt.Printf("ip 变量储存的指针地址: %x\n", ip ) /* 使用指针访问值 */ fmt.Printf("*ip 变量的值: %d\n", *ip ) }
很多人说对象的HashCode方法返回的就是对象的内存地址,包括我在《Java核心编程·卷I》的第5章内容中也发现说是HashCode其值就是对象的内存地址。
//Indicates whether some other object is "equal to" this one. public boolean equals(Object obj) { return (this == obj); }
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; }
/** * Returns a hash code value for the object. This method is * supported for the benefit of hash tables such as those provided by * {@link java.util.HashMap}. * ... * As much as is reasonably practical, the hashCode method defined by * class {@code Object} does return distinct integers for distinct * objects. (This is typically implemented by converting the internal * address of the object into an integer, but this implementation * technique is not required by the * Java™ programming language.) * * @return a hash code value for this object. * @see java.lang.Object#equals(java.lang.Object) * @see java.lang.System#identityHashCode */ public native int hashCode();
static JNINativeMethod methods[] = { {"hashCode", "()I", (void *)&JVM_IHashCode}, {"wait", "(J)V", (void *)&JVM_MonitorWait}, {"notify", "()V", (void *)&JVM_MonitorNotify}, {"notifyAll", "()V", (void *)&JVM_MonitorNotifyAll}, {"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone}, };
JVM_ENTRY(jint, JVM_IHashCode(JNIEnv* env, jobject handle)) JVMWrapper("JVM_IHashCode"); // as implemented in the classic virtual machine; return 0 if object is NULL return handle == NULL ? 0 : ObjectSynchronizer::FastHashCode (THREAD, JNIHandles::resolve_non_null(handle)) ; JVM_END
intptr_t ObjectSynchronizer::FastHashCode (Thread * Self, oop obj) { if (UseBiasedLocking) { ...... // Inflate the monitor to set hash code monitor = ObjectSynchronizer::inflate(Self, obj); // Load displaced header and check it has hash code mark = monitor->header(); assert (mark->is_neutral(), "invariant") ; hash = mark->hash(); if (hash == 0) { hash = get_next_hash(Self, obj); temp = mark->copy_set_hash(hash); // merge hash code into header assert (temp->is_neutral(), "invariant") ; test = (markOop) Atomic::cmpxchg_ptr(temp, monitor, mark); if (test != mark) { // The only update to the header in the monitor (outside GC) // is install the hash code. If someone add new usage of // displaced header, please update this code hash = test->hash(); assert (test->is_neutral(), "invariant") ; assert (hash != 0, "Trivial unexpected object/monitor header usage."); } } // We finally get the hash return hash; }
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 = cast_from_oop<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 = cast_from_oop<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; }
public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); }
public class Student { private String name; private String gender; public Student(String name, String gender) { this.name = name; this.gender = gender; } //省略 Setter,Gettter @Override public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof Student) { Student anotherStudent = (Student) anObject; if (this.getName() == anotherStudent.getName() || this.getGender() == anotherStudent.getGender()) return true; } return false; } }
public static void main(String[] args) { Student student1 = new Student("小明", "male"); Student student2 = new Student("小明", "male"); System.out.println("equals结果:" + student1.equals(student2)); System.out.println("对象1的散列值:" + student1.hashCode() + ",对象2的散列值:" + student2.hashCode()); }
public static void main(String[] args) { Student student1 = new Student("小明", "male"); Student student2 = new Student("小明", "male"); HashMap<Student, String> hashMap = new HashMap<>(); hashMap.put(student1, "小明"); String value = hashMap.get(student2); System.out.println(value); }
public static native int identityHashCode(Object x);
【关注微信公众号获取更多学习资料】 【扫码进入JavaEE/微服务VIP免费公开课】