<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # Java `hashCode()`和`equals()` – 契約,規則和最佳實踐 > 原文: [https://howtodoinjava.com/java/basics/java-hashcode-equals-methods/](https://howtodoinjava.com/java/basics/java-hashcode-equals-methods/) 了解 Java **`hashCode()`和`equals()`方法**,它們的**默認實現以及如何正確覆蓋它們**的信息。 另外,請學習使用 Apache Commons 包的工具類`HashCodeBuilder`和`EqualsBuilder`實現這些方法。 > [**`hashCode()`**](https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode%28%29)和[**`equals()`**](https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals%28java.lang.Object%29)方法已在`Object`類中定義,該類是 Java 對象的父類。 因此,所有 java 對象都繼承這些方法的默認實現。 ```java Table of Contents: 1) Usage of hashCode() and equals() Methods 2) Override the default behavior 3) EqualsBuilder and HashCodeBuilder 4) Generate hashCode() and equals() using Eclipse 5) Important things to remember 6) Special Attention When Using in ORM ``` ## 1\. `hashCode()`和`equals()`方法的用法 1. `equals(Object otherObject)` – 顧名思義,該方法用于簡單地驗證兩個對象的相等性。 默認實現是簡單地檢查兩個對象的對象引用以驗證它們的相等性。 *默認情況下,當且僅當兩個對象存儲在相同的內存地址中時,兩個對象才相等。* 2. ``hashcode()`` – 在運行時為對象返回唯一的整數值。 默認情況下,整數值主要來自堆中對象的內存地址(但并非總是強制性的)。 當此對象需要存儲在某些 [`HashTable`](https://en.wikipedia.org/wiki/Hash_table "Hashtable") 之類的數據結構中時,此哈希碼用于確定存儲桶位置。 #### 1.1 `hashCode()`和`equals()`之間的協定 通常,無論何時覆蓋`equals()`方法,都必須覆蓋`hashCode()`方法,以維護`hashCode()`方法的常規協定,該協定規定**相等的對象必須具有相等的哈希碼**。 * 在 Java 應用程序執行期間,只要在同一個對象上多次調用它,`hashCode`方法必須一致地返回相同的整數,前提是未修改該對象在`equals`比較中使用的信息。 從一個應用程序的一次執行到同一應用程序的另一次執行,此整數不必保持一致。 * 如果根據`equals(Object)`方法兩個對象相等,則在兩個對象中的每個對象上調用`hashCode`方法必須產生相同的整數結果。 * 如果*不是*,則根據 [`equals(java.lang.Object)`](https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#equals-java.lang.Object-) 方法如果兩個對象不相等,則在兩個對象中的每一個上調用`hashCode`方法必須產生不同的整數結果。 但是,程序員應該意識到,為不相等的對象生成不同的整數結果可能會提高哈希表的性能。 ## 2\. 覆蓋`hashCode()`和`equals()`的默認行為 一切正常,直到您沒有在類中覆蓋這些方法中的任何一個。 但是,有時應用程序需要更改某些對象的默認行為。 讓我們理解**為什么我們需要覆蓋`equals`和`hashCode`方法**。 #### 2.1 默認行為 讓我們以您的應用程序具有`Employee`對象的示例為例。 讓我們創建`Employee`類的最小可能結構: ```java public class Employee { private Integer id; private String firstname; private String lastName; private String department; //Setters and Getters } ``` 在`Employee`類之上具有一些非常基本的屬性及其訪問器方法。 現在考慮一個簡單的情況,您需要**比較兩個員工對象**。 ```java public class EqualsTest { public static void main(String[] args) { Employee e1 = new Employee(); Employee e2 = new Employee(); e1.setId(100); e2.setId(100); System.out.println(e1.equals(e2)); //false } } ``` 沒有猜中獎。 上述方法將打印`false`。 但是,在知道兩個對象代表同一位員工之后,這真的正確嗎? 在實時應用程序中,這應該返回`true`。 #### 2.2 我們應該只覆蓋`equals()`方法嗎? 為了實現正確的應用程序行為,我們需要覆蓋`equals()`方法,如下所示: ```java public boolean equals(Object o) { if(o == null) { return false; } if (o == this) { return true; } if (getClass() != o.getClass()) { return false; } Employee e = (Employee) o; return (this.getId() == e.getId()); } ``` 將此方法添加到`Employee`類中,`EqualsTest`將開始返回`true`。 我們完成了嗎? 還沒。 讓我們以不同的方式再次在修改后的`Employee`類上進行測試。 ```java import java.util.HashSet; import java.util.Set; public class EqualsTest { public static void main(String[] args) { Employee e1 = new Employee(); Employee e2 = new Employee(); e1.setId(100); e2.setId(100); //Prints 'true' System.out.println(e1.equals(e2)); Set<Employee> employees = new HashSet<Employee>(); employees.add(e1); employees.add(e2); System.out.println(employees); //Prints two objects } } ``` 上面的類在第二個打印語句中打印兩個對象。 如果兩個員工對象都相等,則在僅存儲唯一對象的`Set`中,在所有兩個對象都引用同一員工之后,`HashSet`中必須只有一個實例。 我們缺少什么? #### 2.3 還覆蓋`hashCode()`方法 我們缺少第二種重要方法`hashCode()`。 如 Java 文檔所述,如果您覆蓋`equals()`方法,則***必須***覆蓋`hashCode()`方法。 因此,讓我們在`Employee`類中添加另一個方法。 ```java @Override public int hashCode() { final int PRIME = 31; int result = 1; result = PRIME * result + getId(); return result; } ``` 在`Employee`類中添加上述方法后,第二條語句僅開始打印第二條語句中的單個對象,并且**從而驗證`e1`和`e2`** 的真實相等性。 ## 3\. `EqualsBuilder`和`HashCodeBuilder`工具類 [Apache Commons](https://commons.apache.org/proper/commons-lang/) 提供了兩個出色的工具類,[`HashCodeBuilder`](https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/builder/HashCodeBuilder.html)和[`EqualsBuilder`](https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/builder/EqualsBuilder.html) ,用于生成`hashCode`和`equals`方法。 以下是其用法: ```java import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; public class Employee { private Integer id; private String firstname; private String lastName; private String department; //Setters and Getters @Override public int hashCode() { final int PRIME = 31; return new HashCodeBuilder(getId()%2==0?getId()+1:getId(), PRIME).toHashCode(); } @Override public boolean equals(Object o) { if (o == null) return false; if (o == this) return true; if (o.getClass() != getClass()) return false; Employee e = (Employee) o; return new EqualsBuilder(). append(getId(), e.getId()). isEquals(); } } ``` ## 4\. 使用 Eclipse 生成`hashCode()`和`equals()` 如果您使用任何代碼編輯器,那么大多數編輯器也能夠為您生成一些良好的結構。 例如, **Eclipse IDE** 可以為您生成`hashCode()`和`equals()`的非常好的實現。 > 右鍵單擊“Java 文件->源->生成`hashCode()`和`equals()`…” ![Generate HashCode and Equals In Eclipse](https://img.kancloud.cn/ee/b7/eeb705c57c531d645a9617350954e0dc_763x439.png) 在 Eclipse 中生成`hashCode()`和`equals()` ## 5\. Java `hashCode()`和`equals()`最佳實踐 1. 始終使用對象的相同屬性來生成`hashCode()`和`equals()`。 在本例中,我們使用了`id`雇員。 2. `equals()`必須與*一致*(如果未修改對象,則它必須保持返回相同的值)。 3. 每當`a.equals(b)`時,則`a.hashCode()`必須與`b.hashCode()`相同。 4. 如果覆蓋一個,則應覆蓋另一個。 ## 6\. 在 *ORM* 中使用時應特別注意 如果您要處理 ORM,請確保**始終使用獲取器,并且切勿在`hashCode()`和`equals()` 中使用字段引用**。 這是有原因的,在 ORM 中,字段有時是延遲加載的,直到調用它們的獲取器方法才可用。 例如,在我們的`Employee`類中,如果我們使用`e1.id == e2.id`。 `id`字段很可能是延遲加載的。 因此,在這種情況下,一個可能為零或為`null`,從而導致錯誤的行為。 但是如果使用`*e1.getId() == e2.getId()*`,即使字段是延遲加載,我們也可以確保; 調用獲取器將首先填充該字段。 這就是我對 **`hashCode()`和`equals()`方法**所了解的全部。 我希望這會對某人有所幫助。 如果您感覺到我在某處缺少任何東西或有什么不對,請發表評論。 我將再次更新此帖子以幫助他人。 學習愉快! [下載源碼](https://app.box.com/s/weem0lzhdg98s28k1sgm "下載源碼")
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看