เข้าใจ
วัตถุประสงค์ของ HashCode () คือการได้รับรหัสแฮชหรือที่เรียกว่ารหัสแฮช; มันส่งคืนจำนวนเต็ม int ฟังก์ชั่นของรหัสแฮชนี้คือการกำหนดตำแหน่งดัชนีของวัตถุในตารางแฮช
HashCode () ถูกกำหนดไว้ใน Object.java ของ JDK ซึ่งหมายความว่าคลาสใดใน Java มีฟังก์ชัน HashCode ()
แม้ว่าแต่ละคลาส Java จะมีฟังก์ชั่น HashCode () อย่างไรก็ตาม hashcode () ของคลาสมีประโยชน์ก็ต่อเมื่อการสร้างและสร้าง "ตารางแฮช" (ดูคำอธิบายด้านล่างสำหรับ "แฮชตาราง") (ฟังก์ชั่นคือการกำหนดตำแหน่งของวัตถุแต่ละรายการของคลาสในตารางแฮช; ในกรณีอื่น ๆ
รายการแฮชด้านบนหมายถึง: คลาสในคอลเลกชัน Java ที่เป็นรายการแฮชเป็นหลักเช่น HashMap, Hashtable และ HashSet
กล่าวอีกนัยหนึ่ง: hashcode () มีประโยชน์เฉพาะใน hashlists แต่ไร้ประโยชน์ในกรณีอื่น ๆ ฟังก์ชั่นของ HashCode () ในตารางแฮชคือการได้รับรหัสแฮชของวัตถุจากนั้นกำหนดตำแหน่งของวัตถุในตารางแฮช
เราทุกคนรู้ว่าตารางแฮชเก็บคู่คีย์-ค่าซึ่งมีลักษณะโดย: มันสามารถดึง "ค่า" ที่สอดคล้องกันได้อย่างรวดเร็วตาม "คีย์" ใช้รหัสแฮชนี้!
สาระสำคัญของตารางแฮชถูกนำไปใช้ผ่านอาร์เรย์ เมื่อเราต้องการได้รับ "ค่า" ที่แน่นอนในตารางแฮชเราต้องการให้องค์ประกอบอยู่ในตำแหน่งที่แน่นอนในอาร์เรย์ ตำแหน่งของอาร์เรย์ได้มาจาก "คีย์"; นอกจากนี้ตำแหน่งของอาร์เรย์คำนวณโดยรหัสแฮชที่สอดคล้องกับ "คีย์"
ด้านล่างเราจะใช้ HashSet เป็นตัวอย่างในการอธิบายในเชิงลึกบทบาทของ HashCode ()
สมมติว่ามี 1,000 องค์ประกอบใน Hashset ฉันควรทำอย่างไรเมื่อแทรกองค์ประกอบ 1001 เนื่องจาก HashSet เป็นชุดสะสมจึงอนุญาตให้มีองค์ประกอบที่ซ้ำกัน
"เปรียบเทียบองค์ประกอบ 1001th ทีละหนึ่งกับ 1,000 องค์ประกอบก่อนหน้านี้"? เห็นได้ชัดว่าประสิทธิภาพนี้ไม่มีประสิทธิภาพเท่ากัน ตารางแฮชช่วยแก้ปัญหานี้ได้เป็นอย่างดี มันคำนวณตำแหน่งขององค์ประกอบในตารางแฮชตามรหัสแฮชจากนั้นแทรกองค์ประกอบลงในตำแหน่งนั้น สำหรับองค์ประกอบเดียวกันโดยธรรมชาติมีเพียงหนึ่งเดียวเท่านั้นที่ถูกบันทึกไว้
จากนี้เราจะเห็นได้ว่าหากสององค์ประกอบเท่ากันรหัสแฮชของพวกเขาจะต้องเท่ากัน แต่อีกวิธีหนึ่งคือไม่ ในตารางแฮช
1. หากวัตถุสองชิ้นมีค่าเท่ากันค่า hashcode () ของพวกเขาจะต้องเหมือนกัน;
2. หากวัตถุทั้งสอง HashCode () มีค่าเท่ากันพวกเขาไม่จำเป็นต้องเท่ากัน
หมายเหตุ: นี่เป็นกรณีในตารางแฮช สิ่งนี้จะต้องเป็นจริงในรายการแฮชที่ไม่ใช่!
ตัวอย่าง
ลองมาดูตัวอย่างที่เฉพาะเจาะจง
Hashtest ชั้นเรียนสาธารณะ {Private int i; สาธารณะ int geti () {return i; } โมฆะสาธารณะ seti (int i) {this.i = i; } public int hashCode () {return i % 10; } โมฆะคงที่สาธารณะสุดท้าย (สตริง [] args) {hashtest a = hashtest ใหม่ (); hashtest b = hashtest ใหม่ (); A.Seti (1); B.Seti (1); ตั้งค่า <hashtest> set = new hashset <hashtest> (); set.add (a); set.add (b); System.out.println (A.HashCode () == B.HashCode ()); System.out.println (A.Equals (B)); System.out.println (set); -ผลลัพธ์ของผลลัพธ์นี้:
True False [com.ubs.sae.test.hashtest@1, com.ubs.sae.test.hashtest@1]
ในตัวอย่างข้างต้นเราเพิ่งเขียนวิธี HashCode ใหม่ จากผลลัพธ์ข้างต้นเราจะเห็นได้ว่าแม้ว่า hashcodes ของวัตถุทั้งสองจะเท่ากัน แต่วัตถุทั้งสองนั้นไม่เท่ากันจริง ๆ แต่เราไม่ได้เขียนวิธีเท่ากับใหม่แล้วเราจะเรียกวิธีการเริ่มต้นของวัตถุเพื่อเปรียบเทียบว่าการอ้างอิงของวัตถุทั้งสองนั้นเหมือนกันหรือไม่ ที่นี่เราวางวัตถุที่สร้างขึ้นใน Hashset และมีเพียงวัตถุที่ไม่ซ้ำกันเท่านั้นที่สามารถเก็บไว้ใน Hashset นั่นคือวัตถุเดียวกัน (ใช้ได้กับวิธี Equals) เท่านั้นที่จะเก็บไว้ได้เพียงอย่างเดียว แต่ที่นี่มีวัตถุสองวัตถุ A และ B ที่วางไว้ใน Hashset ดังนั้น Hashset จึงสูญเสียความหมายของตัวเอง
ในเวลานี้เราเพิ่มวิธีการเท่ากับ:
Hashtest ชั้นเรียนสาธารณะ {Private int i; สาธารณะ int geti () {return i; } โมฆะสาธารณะ seti (int i) {this.i = i; } <span style = "สี:#3366ff;"> <strong> บูลีนสาธารณะเท่ากับ (วัตถุวัตถุ) {ถ้า (วัตถุ == null) {return false; } if (object == สิ่งนี้) {return true; } if (! (วัตถุอินสแตนซ์ของ hashtest)) {return false; } hashtest อื่น ๆ = (hashtest) วัตถุ; if (other.geti () == this.geti ()) {return true; } return false; } </strong> </span> int hashCode () {return i % 10; } โมฆะคงที่สาธารณะสุดท้าย (สตริง [] args) {hashtest a = hashtest ใหม่ (); hashtest b = hashtest ใหม่ (); A.Seti (1); B.Seti (1); ตั้งค่า <hashtest> set = new hashset <hashtest> (); set.add (a); set.add (b); System.out.println (A.HashCode () == B.HashCode ()); System.out.println (A.Equals (B)); System.out.println (set); -ผลลัพธ์ที่ได้ในเวลานี้จะเป็นดังนี้:
จริงจริง [com.ubs.sae.test.hashtest@1]
จากผลลัพธ์เราจะเห็นได้ว่าตอนนี้วัตถุทั้งสองนั้นเท่ากันอย่างสมบูรณ์และมีเพียงวัตถุเดียวเท่านั้นที่ถูกเก็บไว้ใน HashSet
สรุป
1. การมีอยู่ของ HashCode ส่วนใหญ่จะใช้สำหรับการค้นหาความคงทนเช่นแฮชช์แฮชแฮ็ก ฯลฯ HashCode ใช้เพื่อกำหนดที่อยู่ที่เก็บข้อมูลของวัตถุในโครงสร้างการจัดเก็บแฮช;
2. หากวัตถุทั้งสองเหมือนกันมันจะใช้กับวิธี Equals (java.lang.Object) วิธีการ hashcodes ของวัตถุทั้งสองนี้จะต้องเหมือนกัน
3. หากวิธีการที่มีการเขียนใหม่ของวัตถุนั้นถูกเขียนใหม่แล้ว HashCode ของวัตถุควรถูกเขียนใหม่ให้มากที่สุดเท่าที่จะเป็นไปได้และวัตถุที่ใช้โดย HashCode จะต้องสอดคล้องกับวิธีการเท่ากับเท่ากับมิฉะนั้นจะเป็นการละเมิดจุดที่สองที่กล่าวถึงข้างต้น
4. แฮชโฟตอนของวัตถุสองชิ้นเหมือนกันซึ่งไม่ได้หมายความว่าวัตถุทั้งสองนั้นเหมือนกันนั่นคือไม่จำเป็นต้องใช้กับวิธีการเท่ากับ (java.lang.Object) มันสามารถบ่งบอกได้ว่าวัตถุทั้งสองนี้อยู่ในโครงสร้างการจัดเก็บแฮชเช่นแฮชแต้มและพวกมันจะ "เก็บไว้ในตะกร้าเดียวกัน"