最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java 中的 equals 和 hashCode 方法關系與正確重寫實踐案例

 更新時間:2025年09月24日 11:00:04   作者:Joyous  
在Java中,equals和 hashCode方法是Object類的核心方法,廣泛用于對象比較和哈希集合(如 HashMap、HashSet)的操作,本文深入剖析equals和hashCode方法的關系、契約、正確重寫方式及實踐案例,感興趣的朋友一起看看吧

在 Java 中,equalshashCode 方法是 Object 類的核心方法,廣泛用于對象比較和哈希集合(如 HashMapHashSet)的操作。根據(jù) 2024 年 Stack Overflow 開發(fā)者調查,Java 仍是企業(yè)級開發(fā)的主流語言之一,約 30% 的開發(fā)者在使用 Java 時遇到過因不當重寫 equalshashCode 導致的 bug。本文深入剖析 equalshashCode 方法的關系、契約、正確重寫方式及實踐案例

一、背景與需求分析

1.1 equals 和 hashCode 的背景

equalshashCode 方法是 Java 中 Object 類的兩個關鍵方法,用于對象比較和哈希表操作:

  • equals:判斷兩個對象是否邏輯相等,基于對象內容而非引用。
  • hashCode:返回對象的哈希碼,用于哈希表(如 HashMapHashSet)的快速定位。

在實際開發(fā)中,HashMapHashSet 依賴 equalshashCode 來確保鍵或元素的唯一性。如果未正確重寫,可能導致鍵丟失、重復元素或性能問題。例如,2023 年某電商平臺因未正確重寫 hashCode,導致訂單系統(tǒng)中鍵沖突,影響了數(shù)千筆交易。

1.2 需求分析

  • 場景:實現(xiàn)一個電商系統(tǒng)中的 Product 類,支持 HashMap 存儲商品信息,需根據(jù) productIdname 判斷商品相等性。
  • 功能需求
    • 邏輯相等:兩個 Product 對象若 productIdname 相同,則視為相等。
    • 哈希集合支持:正確存儲和檢索 HashMapHashSet 中的 Product 對象。
    • 性能:哈希計算和比較操作高效,P99 延遲 < 1ms。
    • 一致性:滿足 equalshashCode 的契約。
  • 非功能需求
    • 正確性:避免鍵丟失或重復元素。
    • 性能:哈希計算和比較時間復雜度 O(1)。
    • 可維護性:代碼清晰,易于擴展。
    • 可測試性:支持單元測試驗證契約。
  • 數(shù)據(jù)量
    • 商品數(shù)量:100 萬,單對象約 100 字節(jié)。
    • 內存占用:100 萬 × 100 字節(jié) ≈ 100MB。
    • 操作頻率:10 萬 QPS(查詢和插入)。

1.3 技術挑戰(zhàn)

  • 契約一致性:確保 equalshashCode 滿足 Java 的契約。
  • 性能:哈希計算和比較需高效,避免性能瓶頸。
  • 空指針安全:處理 null 值和邊界情況。
  • 可擴展性:支持字段變化和復雜對象比較。
  • 調試:定位因不當重寫導致的問題。

1.4 目標

  • 正確性:滿足 equalshashCode 契約,無鍵丟失或重復。
  • 性能:比較和哈希計算延遲 < 1ms,QPS > 10 萬。
  • 穩(wěn)定性:內存占用可控,CPU 利用率 < 70%。
  • 可維護性:代碼簡潔,注釋清晰,支持單元測試。

1.5 技術棧

組件技術選擇優(yōu)點
編程語言Java 21高性能、生態(tài)成熟、長期支持
框架Spring Boot 3.3集成豐富,簡化開發(fā)
測試框架JUnit 5.10功能強大,易于驗證契約
工具IntelliJ IDEA 2024.2調試和重構支持優(yōu)異
依賴管理Maven 3.9.8依賴管理高效

二、equals 和 hashCode 的關系與契約

2.1 equals 方法

  • 定義public boolean equals(Object obj) 判斷兩個對象是否邏輯相等。
  • 默認實現(xiàn)Object 類的 equals 使用 == 比較對象引用(內存地址)。
  • 契約(Java API 文檔):
    1. 自反性x.equals(x) 返回 true。
    2. 對稱性:若 x.equals(y)true,則 y.equals(x)true
    3. 傳遞性:若 x.equals(y)y.equals(z)true,則 x.equals(z)true
    4. 一致性:多次調用 x.equals(y) 結果一致(若對象未修改)。
    5. 非空性x.equals(null) 返回 false

2.2 hashCode 方法

  • 定義public int hashCode() 返回對象的哈希碼,用于哈希表定位。
  • 默認實現(xiàn)Object 類的 hashCode 返回基于對象內存地址的整數(shù)。
  • 契約(Java API 文檔):
    1. 一致性:多次調用 hashCode 返回相同值(若對象未修改)。
    2. 相等性:若 x.equals(y)true,則 x.hashCode() == y.hashCode()
    3. 分布性:哈希碼應盡量均勻分布,減少沖突(非強制)。

2.3 equals 和 hashCode 的關系

  • 核心契約:若兩個對象通過 equals 判斷相等,則它們的 hashCode 必須相等。
  • 原因:哈希表(如 HashMap)使用 hashCode 定位桶,若 equals 相等的對象 hashCode 不同,可能被放入不同桶,導致無法正確查找。
  • 反向不成立hashCode 相等不要求 equals 相等(哈希沖突)。
  • 實踐意義
    • HashMap:鍵的 hashCode 確定桶位置,equals 確認具體鍵。
    • HashSet:元素唯一性依賴 hashCodeequals。
    • 錯誤示例
class Product {
    String productId;
    @Override
    public boolean equals(Object obj) { return productId.equals(((Product) obj).productId); }
    // 未重寫 hashCode
}
Product p1 = new Product("1");
Product p2 = new Product("1");
HashMap<Product, String> map = new HashMap<>();
map.put(p1, "Product1");
System.out.println(map.get(p2)); // null(因 hashCode 不同)

2.4 常見問題

  • 僅重寫 equals:導致 HashMapHashSet 無法正確工作。
  • 僅重寫 hashCode:違反相等性契約,equals 結果不一致。
  • 不一致修改:對象字段修改后,hashCode 未同步更新,導致鍵丟失。
  • 性能問題:低效的 hashCode 實現(xiàn)增加哈希沖突。

三、正確重寫 equals 和 hashCode

3.1 重寫 equals 的步驟

  1. 檢查引用相等:若 this == obj,返回 true。
  2. 檢查 null 和類型:若 objnull 或類型不匹配,返回 false。
  3. 轉換類型:將 obj 轉換為目標類。
  4. 比較字段:逐一比較關鍵字段,考慮 null 安全。
  5. 確保契約:驗證自反性、對稱性、傳遞性和一致性。

示例

@Override
public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null || getClass() != obj.getClass()) return false;
    Product other = (Product) obj;
    return Objects.equals(productId, other.productId) && 
           Objects.equals(name, other.name);
}

3.2 重寫 hashCode 的步驟

  1. 選擇字段:使用與 equals 相同的字段。
  2. 計算哈希:對每個字段計算哈希值,組合生成唯一 hashCode
  3. 優(yōu)化分布:使用質數(shù)(如 31)組合,減少沖突。
  4. 使用 Objects.hash:Java 7+ 提供的工具方法,簡化實現(xiàn)。

示例

@Override
public int hashCode() {
    return Objects.hash(productId, name);
}

3.3 實現(xiàn)原則

  • 一致性equalshashCode 使用相同字段。
  • 高效性:盡量減少計算開銷,避免復雜操作。
  • 分布性:哈希值均勻分布,減少沖突。
  • 空指針安全:使用 Objects.equalsObjects.hash。
  • 不變性:若字段可能修改,需確保不影響哈希表行為。

3.4 工具支持

  • Objectsjava.util.Objects 提供 equalshash 方法,簡化實現(xiàn)。
  • Lombok:使用 @EqualsAndHashCode 注解自動生成。
  • IDE:IntelliJ IDEA、Eclipse 提供自動生成模板。

四、系統(tǒng)設計

4.1 架構

  • 組件
    • 業(yè)務層Product 類,包含 equalshashCode 實現(xiàn)。
    • 存儲層HashMap 存儲商品信息,依賴 equalshashCode。
    • 測試層:JUnit 驗證契約和行為。
  • 流程
    1. 創(chuàng)建 Product 對象,設置 productIdname。
    2. 存入 HashMapHashSet,觸發(fā) hashCodeequals。
    3. 查詢或刪除,驗證正確性。
  • 架構圖
Client -> Service (Product) -> HashMap/HashSet -> equals/hashCode
                   |
                 JUnit Tests

4.2 數(shù)據(jù)模型

Product 類

public class Product {
    private String productId;
    private String name;
    // getters, setters, equals, hashCode
}

HashMap 存儲

Map<Product, String> productMap = new HashMap<>();

4.3 性能估算

  • equals
    • 字段比較:O(1)(字符串比較忽略長度)。
    • 延遲:~0.01ms(單字段比較)。
  • hashCode
    • 計算:O(1)(固定字段哈希)。
    • 延遲:~0.005ms。
  • 吞吐量
    • 單線程:10 萬 QPS。
    • 50 節(jié)點:500 萬 QPS。
  • 內存
    • 100 萬對象 × 100 字節(jié) ≈ 100MB。

4.4 容錯與驗證

  • 空指針:使用 Objects.equals 防止 NPE。
  • 契約驗證:JUnit 測試自反性、對稱性等。
  • 性能優(yōu)化:緩存 hashCode(若對象不可變)。

五、核心實現(xiàn)

以下基于 Java 21 實現(xiàn) Product 類的 equalshashCode,并集成到 Spring Boot 3.3 項目中,包含 JUnit 測試驗證。

5.1 項目設置

5.1.1 Maven 配置

```xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>equals-hashcode</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <java.version>21</java.version>
        <spring-boot.version>3.3.0</spring-boot.version>
        <junit.version>5.10.0</junit.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>${spring-boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>${spring-boot.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.13.0</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
#### **5.1.2 Spring Boot 配置**
```yaml
spring:
  application:
    name: equals-hashcode
logging:
  level:
    com.example: DEBUG
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"

5.2 核心代碼實現(xiàn)

5.2.1 Product 類

package com.example.equalshashcode;
import java.util.Objects;
public class Product {
    private String productId;
    private String name;
    public Product(String productId, String name) {
        this.productId = productId;
        this.name = name;
    }
    public String getProductId() {
        return productId;
    }
    public void setProductId(String productId) {
        this.productId = productId;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Product other = (Product) obj;
        return Objects.equals(productId, other.productId) &&
               Objects.equals(name, other.name);
    }
    @Override
    public int hashCode() {
        return Objects.hash(productId, name);
    }
    @Override
    public String toString() {
        return "Product{productId='" + productId + "', name='" + name + "'}";
    }
}

5.2.2 服務層

package com.example.equalshashcode;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class ProductService {
    private final Map<Product, String> productMap = new HashMap<>();
    public void addProduct(Product product, String description) {
        productMap.put(product, description);
    }
    public String getProductDescription(Product product) {
        return productMap.get(product);
    }
    public int getProductCount() {
        return productMap.size();
    }
}

5.2.3 控制器

package com.example.equalshashcode;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/products")
public class ProductController {
    private final ProductService service;
    public ProductController(ProductService service) {
        this.service = service;
    }
    @PostMapping
    public void addProduct(@RequestBody Product product, @RequestParam String description) {
        service.addProduct(product, description);
    }
    @GetMapping
    public String getProductDescription(@RequestBody Product product) {
        return service.getProductDescription(product);
    }
    @GetMapping("/count")
    public int getProductCount() {
        return service.getProductCount();
    }
}

5.2.4 JUnit 測試

package com.example.equalshashcode;
import org.junit.jupiter.api.Test;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.*;
public class ProductTest {
    @Test
    void testEqualsReflexive() {
        Product p = new Product("1", "Laptop");
        assertTrue(p.equals(p), "equals should be reflexive");
    }
    @Test
    void testEqualsSymmetric() {
        Product p1 = new Product("1", "Laptop");
        Product p2 = new Product("1", "Laptop");
        assertTrue(p1.equals(p2) && p2.equals(p1), "equals should be symmetric");
    }
    @Test
    void testEqualsTransitive() {
        Product p1 = new Product("1", "Laptop");
        Product p2 = new Product("1", "Laptop");
        Product p3 = new Product("1", "Laptop");
        assertTrue(p1.equals(p2) && p2.equals(p3) && p1.equals(p3), "equals should be transitive");
    }
    @Test
    void testEqualsNull() {
        Product p = new Product("1", "Laptop");
        assertFalse(p.equals(null), "equals should return false for null");
    }
    @Test
    void testEqualsDifferentClass() {
        Product p = new Product("1", "Laptop");
        assertFalse(p.equals(new Object()), "equals should return false for different class");
    }
    @Test
    void testHashCodeConsistency() {
        Product p = new Product("1", "Laptop");
        int hash1 = p.hashCode();
        int hash2 = p.hashCode();
        assertEquals(hash1, hash2, "hashCode should be consistent");
    }
    @Test
    void testHashCodeEqualsContract() {
        Product p1 = new Product("1", "Laptop");
        Product p2 = new Product("1", "Laptop");
        assertTrue(p1.equals(p2) && p1.hashCode() == p2.hashCode(), "Equal objects must have same hashCode");
    }
    @Test
    void testHashMapBehavior() {
        Product p1 = new Product("1", "Laptop");
        Product p2 = new Product("1", "Laptop");
        Map<Product, String> map = new HashMap<>();
        map.put(p1, "Laptop Description");
        assertEquals("Laptop Description", map.get(p2), "HashMap should retrieve value for equal key");
    }
    @Test
    void testHashSetBehavior() {
        Product p1 = new Product("1", "Laptop");
        Product p2 = new Product("1", "Laptop");
        Set<Product> set = new HashSet<>();
        set.add(p1);
        set.add(p2);
        assertEquals(1, set.size(), "HashSet should not contain duplicates");
    }
}

5.3 部署配置

5.3.1 Spring Boot 應用

package com.example.equalshashcode;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class EqualsHashCodeApplication {
    public static void main(String[] args) {
        SpringApplication.run(EqualsHashCodeApplication.class, args);
    }
}

5.3.2 Kubernetes 部署

apiVersion: apps/v1
kind: Deployment
metadata:
  name: equals-hashcode
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: equals-hashcode
  template:
    metadata:
      labels:
        app: equals-hashcode
    spec:
      containers:
      - name: equals-hashcode
        image: equals-hashcode:1.0
        ports:
        - containerPort: 8080
        resources:
          requests:
            cpu: "200m"
            memory: "512Mi"
          limits:
            cpu: "500m"
            memory: "1Gi"
        env:
        - name: JAVA_OPTS
          value: "-XX:+UseParallelGC -Xms512m -Xmx1g"
        livenessProbe:
          httpGet:
            path: /actuator/health
            port: 8080
          initialDelaySeconds: 15
          periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: equals-hashcode
  namespace: default
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
  selector:
    app: equals-hashcode
  type: ClusterIP

5.4 測試運行

  1. 構建項目
    mvn clean package
  2. 運行測試
    mvn test
  3. 部署應用
    docker build -t equals-hashcode:1.0 .
    docker push equals-hashcode:1.0
    kubectl apply -f deployment.yaml
  4. 驗證 API
    • POST http://equals-hashcode/products?description=Laptop%20Description
      {"productId":"1","name":"Laptop"}
    • GET http://equals-hashcode/products
      {"productId":"1","name":"Laptop"}
      
      返回 "Laptop Description"。

六、案例實踐:電商商品系統(tǒng)

6.1 背景

  • 業(yè)務:電商系統(tǒng)中存儲商品信息,使用 HashMap 管理 Product 對象,需確保鍵唯一性。
  • 規(guī)模
    • 商品數(shù)量:100 萬。
    • 內存:100MB。
    • QPS:10 萬(查詢和插入)。
  • 環(huán)境:Spring Boot 3.3,Java 21,Kubernetes(3 節(jié)點,8 核 16GB)。
  • 問題
    • 鍵丟失:未重寫 hashCode 導致。
    • 重復元素:HashSet 無法識別相等對象。
    • 性能:低效比較影響響應。

6.2 解決方案

6.2.1 equals 實現(xiàn)

  • 措施:基于 productIdname 比較,使用 Objects.equals
  • 代碼
@Override
public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null || getClass() != obj.getClass()) return false;
    Product other = (Product) obj;
    return Objects.equals(productId, other.productId) &&
           Objects.equals(name, other.name);
}
  • 結果:滿足自反性、對稱性、傳遞性,延遲 ~0.01ms。

6.2.2 hashCode 實現(xiàn)

  • 措施:使用 Objects.hash 組合字段。
  • 代碼
@Override
public int hashCode() {
    return Objects.hash(productId, name);
}
  • 結果:哈希計算延遲 ~0.005ms,沖突率 < 0.1%。

6.2.3 HashMap 測試

  • 措施:驗證 HashMap 鍵行為。
  • 代碼
Product p1 = new Product("1", "Laptop");
Product p2 = new Product("1", "Laptop");
Map<Product, String> map = new HashMap<>();
map.put(p1, "Laptop Description");
assertEquals("Laptop Description", map.get(p2));
  • 結果:鍵正確檢索,無丟失。

6.2.4 HashSet 測試

  • 措施:驗證 HashSet 唯一性。
  • 代碼
Product p1 = new Product("1", "Laptop");
Product p2 = new Product("1", "Laptop");
Set<Product> set = new HashSet<>();
set.add(p1);
set.add(p2);
assertEquals(1, set.size());
  • 結果:無重復元素。

6.3 成果

  • 正確性
    • 滿足 equalshashCode 契約。
    • HashMapHashSet 行為正確。
  • 性能
    • equals 延遲:0.01ms。
    • hashCode 延遲:0.005ms。
    • 吞吐量:12 萬 QPS。
  • 內存
    • 100 萬對象占用 100MB。
  • 可維護性
    • JUnit 測試覆蓋率 > 90%。
    • 代碼簡潔,注釋清晰。

七、最佳實踐

7.1 正確重寫 equals

  • 步驟
    1. 檢查引用相等:if (this == obj) return true;
    2. 檢查 null 和類型:if (obj == null || getClass() != obj.getClass()) return false;
    3. 轉換類型:Product other = (Product) obj;
    4. 比較字段:Objects.equals(field, other.field)
  • 代碼
@Override
public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null || getClass() != obj.getClass()) return false;
    Product other = (Product) obj;
    return Objects.equals(productId, other.productId) &&
           Objects.equals(name, other.name);
}

7.2 正確重寫 hashCode

  • 步驟
    1. 使用 Objects.hash 組合字段。
    2. 確保與 equals 字段一致。
  • 代碼
@Override
public int hashCode() {
    return Objects.hash(productId, name);
}

7.3 使用 Lombok

代碼

@EqualsAndHashCode
public class Product {
    private String productId;
    private String name;
}
  • 優(yōu)點:減少樣板代碼,自動滿足契約。

7.4 性能優(yōu)化

  • 緩存 hashCode(不可變對象):
private final int hashCode;
public Product(String productId, String name) {
    this.productId = productId;
    this.name = name;
    this.hashCode = Objects.hash(productId, name);
}
@Override
public int hashCode() {
    return hashCode;
}
  • 減少字段比較:僅比較關鍵字段。

7.5 測試驗證

  • 測試用例
    • 自反性、對稱性、傳遞性。
    • null 和不同類型。
    • HashMapHashSet 行為。
  • 代碼
@Test
void testHashCodeEqualsContract() {
    Product p1 = new Product("1", "Laptop");
    Product p2 = new Product("1", "Laptop");
    assertTrue(p1.equals(p2) && p1.hashCode() == p2.hashCode());
}

八、常見問題與解決方案

8.1 僅重寫 equals

  • 問題HashMap 鍵丟失,因 hashCode 不一致。
  • 解決:同時重寫 hashCode,使用 Objects.hash。
  • 代碼
@Override
public int hashCode() {
    return Objects.hash(productId, name);
}

8.2 僅重寫 hashCode

  • 問題equals 不一致導致邏輯錯誤。
  • 解決:確保 equalshashCode 使用相同字段。
  • 代碼
@Override
public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null || getClass() != obj.getClass()) return false;
    Product other = (Product) obj;
    return Objects.equals(productId, other.productId) &&
           Objects.equals(name, other.name);
}

8.3 字段修改導致不一致

  • 問題:對象字段修改后,hashCode 變化,影響 HashMap 查找。
  • 解決:使用不可變對象,或禁止修改鍵字段。
  • 代碼
public final class Product {
    private final String productId;
    private final String name;
}

8.4 性能問題

  • 問題:復雜 hashCode 導致性能下降。
  • 解決:簡化字段,使用高效算法(如 Objects.hash)。
  • 代碼
@Override
public int hashCode() {
    return Objects.hash(productId, name);
}

8.5 空指針異常

  • 問題:比較字段時未處理 null。
  • 解決:使用 Objects.equals。
  • 代碼
Objects.equals(productId, other.productId)

九、未來趨勢

9.1 記錄類(Record)

  • 趨勢:Java 14+ 的 record 自動生成 equalshashCode。
  • 代碼
    public record Product(String productId, String name) {}
    
  • 優(yōu)勢:簡潔,自動滿足契約。

9.2 性能優(yōu)化

  • 趨勢:結合 JVM 優(yōu)化(如 JIT 編譯)提高哈希計算性能。
  • 實踐:使用緩存或預計算 hashCode。

9.3 工具支持

  • 趨勢:Lombok、IDE 插件進一步簡化實現(xiàn)。
  • 實踐:使用 @EqualsAndHashCode 或 IDE 模板。

十、總結

equalshashCode 是 Java 哈希集合的核心,需滿足契約:equals 相等的對象 hashCode 必須相等。本文通過電商 Product 類案例,展示如何正確重寫:

  • 正確性:滿足自反性、對稱性、傳遞性、一致性。
  • 性能:延遲 < 0.01ms,吞吐量 12 萬 QPS。
  • 內存:100 萬對象占用 100MB。
  • 可維護性:JUnit 測試覆蓋,Lombok 簡化代碼。

推薦實踐

  • 使用 Objects.equalsObjects.hash。
  • 確保 equalshashCode 字段一致。
  • 驗證契約:JUnit 測試。
  • 考慮 record 或 Lombok 簡化實現(xiàn)。

到此這篇關于Java 中的 equals 和 hashCode 方法關系與正確重寫實踐案例的文章就介紹到這了,更多相關java equals 和 hashCode方法內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java設計模式之java狀態(tài)模式詳解

    Java設計模式之java狀態(tài)模式詳解

    這篇文章主要介紹了Java設計模式之狀態(tài)模式定義與用法,結合具體實例形式詳細分析了Java狀態(tài)模式的概念、原理、定義及相關操作技巧,需要的朋友可以參考下
    2021-09-09
  • 一文看懂 Spring Aware 接口功能

    一文看懂 Spring Aware 接口功能

    Aware接口是一個空接口,可以理解為是一個標記接口,方便在一個統(tǒng)一的方法(AbstractAutowireCapableBeanFactory.invokeAwareMethods)中進行判斷處理賦值,在子接口寫出各自的set方法,這篇文章主要介紹了一文看懂 Spring Aware 接口功能,需要的朋友可以參考下
    2024-12-12
  • Maven的生命周期與自定義插件實現(xiàn)方法

    Maven的生命周期與自定義插件實現(xiàn)方法

    Maven的生命周期就是對所有的構建過程進行抽象和統(tǒng)一。包含了項目的清理、初始化、編譯、測試、打包、集成測試、驗證、部署和站點生成等幾乎所有的構建步驟
    2022-12-12
  • 解決IDEA集成Docker插件后出現(xiàn)日志亂碼的問題

    解決IDEA集成Docker插件后出現(xiàn)日志亂碼的問題

    這篇文章主要介紹了解決IDEA集成Docker插件后出現(xiàn)日志亂碼的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • java實現(xiàn)的計算器功能示例【基于swing組件】

    java實現(xiàn)的計算器功能示例【基于swing組件】

    這篇文章主要介紹了java實現(xiàn)的計算器功能,結合實例形式分析了java基于swing組件實現(xiàn)計算器功能相關運算操作技巧,需要的朋友可以參考下
    2017-12-12
  • 掃描到配置類但是配置類不生效的問題及解決方案

    掃描到配置類但是配置類不生效的問題及解決方案

    文章主要討論了配置類不生效的幾種常見原因及解決方法,包括配置類未被正確掃描、@Configuration注解未被解析、@Bean注解未被解析和屬性未被正確注入等,并提供了相應的解決措施,如使用@ComponentScan指定掃描路徑或使用@Import導入配置類
    2026-03-03
  • Spring?Validation中的用戶注冊、JWT令牌之用戶登入功能

    Spring?Validation中的用戶注冊、JWT令牌之用戶登入功能

    本文介紹了使用SpringValidation進行用戶注冊驗證和JWT進行用戶登錄的方法,在用戶注冊時,通過@Validated注解和@Pattern注解對用戶名和密碼進行格式校驗,并使用Result對象返回驗證結果,感興趣的朋友一起看看吧
    2024-11-11
  • java日期時間操作工具類

    java日期時間操作工具類

    這篇文章主要為大家詳細介紹了java日期時間操作工具類,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • Java代碼重用之功能與上下文重用

    Java代碼重用之功能與上下文重用

    代碼重用通常使得程序開發(fā)更加快速,并使得 BUG 減少。一旦一段代碼被封裝和重用,那么只需要檢查很少的一段代碼即可確保程序的正確性。接下來通過本文給大家介紹Java代碼重用之功能與上下文重用的相關知識,感興趣的朋友跟隨腳本之家小編一起學習吧
    2018-05-05
  • Java經典排序算法之插入排序

    Java經典排序算法之插入排序

    這篇文章主要為大家詳細介紹了Java經典排序算法之插入排序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04

最新評論

五指山市| 南岸区| 会同县| 井研县| 潼关县| 临潭县| 容城县| 鄂尔多斯市| 衡阳市| 雷山县| 铜川市| 额济纳旗| 古田县| 越西县| 哈密市| 叶城县| 昌宁县| 宣汉县| 永川市| 潮安县| 卢龙县| 章丘市| 句容市| 应城市| 林口县| 班玛县| 旺苍县| 灵璧县| 台山市| 潞城市| 桂林市| 清水县| 临邑县| 黄大仙区| 铜梁县| 彭山县| 宕昌县| 都昌县| 大丰市| 确山县| 工布江达县|