Java Collections – hashCode() และ equals() – วิธีการแทนที่ equals() และ hashcode() Method ใน Java?
เผยแพร่แล้ว: 2018-08-08
equals()
และ hashCode()
ใน Java เป็นวิธีการพื้นฐานสองวิธีซึ่งประกาศไว้ในคลาสอ็อบเจ็กต์และไลบรารี Java บางส่วนหรือหลัก
หากคุณมีข้อกังวลข้อใดข้อหนึ่งด้านล่างใน Java คุณมาถูกที่แล้ว
- Java Practices -> Implementing equals
- แทนที่ – การแทนที่เท่ากับและ hashCode ใน Java
- วิธีการแทนที่เท่ากับ () วิธีการใน java
- วิธีแทนที่เมธอด hashCode() ใน java
- วิธีการแทนที่เท่ากับและวิธีการ hashCode ใน Java
- อย่างไรและทำไมต้องแทนที่วิธีเท่ากับใน Java
- เหตุใดจึงแทนที่ hashcode() เสมอ หากการแทนที่เท่ากับ ()
มาดูตัวอย่างง่ายๆ เพื่อทำความเข้าใจ Reference Equality
และ Logical Equality
ก่อน ตัวดำเนินการความเท่าเทียมกัน (==) เปรียบเทียบการอ้างอิง (ที่อยู่ในหน่วยความจำ) ของสตริงทั้งสองเป็นตัวเลขที่แตกต่างกันสองตัว ซึ่งเรียกว่า Reference equality
Logical equality
เปรียบเทียบข้อมูลของวัตถุแทนที่จะเป็นค่าของข้อมูลอ้างอิง
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
package com . crunchify . tutorials ; /** * @author Crunchify.com */ public class CrunchifyLogicalVsReferenceEqality { public static void main ( String [ ] args ) { String strA = new String ( "eBay" ) ; String strB = new String ( "eBay" ) ; String strC = new String ( "Paypal" ) ; // Create a String reference and assign an existing String's reference to it // so that both references point to the same String object in memory. String strD = strA ; // Print out the results of various equality checks // Reference Equality System . out . println ( "Reference Equality Result:" ) ; System . out . println ( strA == strB ) ; System . out . println ( strA == strC ) ; System . out . println ( strA == strD ) ; // Logical Equality System . out . println ( "\nLogical Equality Result:" ) ; System . out . println ( strA . equals ( strB ) ) ; System . out . println ( strA . equals ( strC ) ) ; System . out . println ( strA . equals ( strD ) ) ; } } |
เอาท์พุท:
1 2 3 4 5 6 7 8 9 |
Reference Equality Result : false false true Logical Equality Result : true false true |
hashCode และ เท่ากับ มีความเกี่ยวข้องอย่างใกล้ชิด:
- หากคุณแทนที่ equals คุณต้องแทนที่ hashCode
- hashCode ต้องสร้างค่าที่เท่ากันสำหรับอ็อบเจกต์ที่เท่ากัน
- เท่ากับ และ hashCode ต้องขึ้นอยู่
same set of significant fields
เดียวกัน คุณต้องใช้ฟิลด์ชุดเดียวกันในทั้งสองวิธี คุณไม่จำเป็นต้องใช้ฟิลด์ทั้งหมด ตัวอย่างเช่น เขตข้อมูลจากการคำนวณที่ขึ้นอยู่กับช่องอื่นๆ ควรละเว้นจากequals
และhashCode
เมื่อใช้งาน เท่ากับ ฟิลด์จะถูกเปรียบเทียบแตกต่างกันตามประเภท:
- ฟิลด์อ็อบเจ็กต์รวมถึงคอลเล็กชัน : use equals
- type-safe enumerations : ใช้ เท่ากับ หรือ == (ในกรณีนี้จะเท่ากัน)
- ฟิลด์ออบเจ็กต์อาจเป็นโมฆะ: ใช้ทั้ง == และ เท่ากับ
- ฟิลด์อาร์เรย์ : ใช้
Arrays.equals
- ฟิลด์ดั้งเดิมอื่นที่ไม่ใช่ float หรือ double : use ==
-
float
: แปลงเป็น int โดยใช้Float.floatToIntBits ,
จากนั้นใช้ == -
double
: แปลงเป็น long โดยใช้Double.doubleToLongBits
จากนั้นใช้ ==
การใช้ hashCode :
- หากคลาสแทนที่ เท่ากับ จะต้องแทนที่ hashCode
- เมื่อทั้งสองถูกแทนที่ เท่ากับ และ hashCode ต้องใช้เขตข้อมูลชุดเดียวกัน
- ถ้าสองอ็อบเจ็กต์เท่ากัน ค่า hashCode ของพวกมันจะต้องเท่ากันด้วย
- หากวัตถุไม่เปลี่ยนรูป hashCode เป็นตัวเลือกสำหรับการแคชและการเริ่มต้นที่ขี้เกียจ
เป็นความเข้าใจผิดที่เป็นที่นิยมที่ hashCode จัดเตรียมตัวระบุเฉพาะสำหรับอ็อบเจ็กต์ มันไม่ใช่.
ตามสัญญาทั่วไป เมธอด equals()
ใน Java จะต้องเป็นแบบสะท้อนกลับ สมมาตร สกรรมกริยา สอดคล้องกัน และการอ้างอิงที่ไม่ใช่ค่าว่างใดๆ จะต้องคืนค่าเท็จ กล่าวอีกนัยหนึ่ง สำหรับค่า a, b และ c โดยพลการ การทดสอบต่อไปนี้จะต้องผ่านเสมอ:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/ reflexive property assertTrue ( a . equals ( a ) ) ; // symmetric property assertTrue ( a . equals ( b ) == b . equals ( a ) ) ; // transitive property if ( a . equals ( b ) && b.equals(c) ) { assertTrue( a.equals(c) ); } // consistency property assertTrue ( a . equals ( b ) == a . equals ( b ) ) ; // non-null property assertFalse ( a . equals ( null ) ) ; |
สำหรับแนวทางปฏิบัติที่ดีที่สุด ให้ใช้ขั้นตอนด้านล่างเพื่อนำวิธี equals() ไปใช้:
- ใช้สิ่งนี้ == เพื่อตรวจสอบความเท่าเทียมกันอ้างอิง
- ใช้
instanceof
เพื่อทดสอบประเภทอาร์กิวเมนต์ที่ถูกต้อง - ส่งอาร์กิวเมนต์เป็นประเภทที่ถูกต้อง
- เปรียบเทียบช่องที่สำคัญเพื่อความเท่าเทียมกัน
นี่คือตัวอย่างที่สมบูรณ์
CrunchifyImplementEqualsHashCode.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
package crunchify . com . tutorials ; /** * * @author Crunchify.com * How to Override equals() method in Java? * How to Override hasCode() method in Java? * version:1.2 * */ public class CrunchifyImplementEqualsHashCode { public static void main ( String [ ] args ) { CrunchifyImplementEqualsHashCode crunchifyTest = new CrunchifyImplementEqualsHashCode ( ) ; Crunchify one = new Crunchify ( 1 ) ; Crunchify two = new Crunchify ( 1 ) ; crunchifyTest . test1 ( one , two ) ; Crunchify three = new Crunchify ( 1 ) ; Crunchify four = new Crunchify ( 2 ) ; crunchifyTest . test2 ( three , four ) ; } public void test1 ( Crunchify one , Crunchify two ) { if ( one . equals ( two ) ) { System . out . println ( "Test1: One and Two are equal" ) ; } else { System . out . println ( "Test1: One and Two are not equal" ) ; } } public void test2 ( Crunchify three , Crunchify four ) { if ( three . equals ( four ) ) { System . out . println ( "Test2: Three and Four are equal" ) ; } else { System . out . println ( "Test2: Three and Four are not equal" ) ; } } } class Crunchify { private int value ; Crunchify ( int val ) { value = val ; } public int getValue ( ) { return value ; } // The method does override or implement a method declared in a supertype. @Override public boolean equals ( Object o ) { // null check if ( o == null ) { return false ; } // this instance check if ( this == o ) { return true ; } // instanceof Check and actual value check if ( ( o instanceof Crunchify ) && (((Crunchify) o).getValue() == this.value)) { return true; } else { return false ; } } @Override public int hashCode ( ) { int result = 0 ; result = ( int ) ( value / 11 ) ; return result ; } } |
เอาต์พุตคอนโซล Eclipse:
1 2 |
Test1 : One and Two are equal Test2 : Three and Four are not equal |