首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 進階教程(二):HashSet 核心機制與最佳實踐

     編輯:Java 相關知識

HashSet 是 Java 集合框架中最常用的去重容器,基於 HashMap 實現,提供 O(1) 平均時間複雜度的增刪查操作。深入理解其底層機制對避免常見陷阱至關重要。

核心特性

  • 不允許重複元素(通過 equals/hashCode 判斷)
  • 允許單個 null 元素
  • 無序存儲,迭代順序不固定
  • 非線程安全

基本操作示例

public static void testNormal() {
    Set set = new HashSet();
    set.add("字符串");
    set.add(new Integer(1));
    set.add(123.45); // 自動裝箱
    
    System.out.println(set.size()); // 3
    set.add("字符串"); // 重複忽略
    System.out.println(set.size()); // 仍為 3
    
    System.out.println(set.contains(123.45)); // true
    set.remove(123.45);
    System.out.println(set.size()); // 2
}

關鍵機制:equals 與 hashCode 契約

class MyObject {
    private String name;
    private int age;
    
    @Override
    public boolean equals(Object obj) {
        if (obj == null || !(obj instanceof MyObject)) return false;
        MyObject o = (MyObject) obj;
        return this.age == o.age && this.name.equals(o.name);
    }
    
    @Override
    public int hashCode() {
        return name.hashCode() + String.valueOf(age).hashCode();
    }
}

常見陷阱與解決方案

陷阱 1:可變對象導致 hashCode 變化

MyObject obj = new MyObject("java2000", 2);
set.add(obj);
obj.setAge(3); // 修改導致 hashCode 變化
set.contains(obj); // 可能返回 false!
set.add(obj); // 重複添加成功,造成內存洩漏風險

解決方案:緩存 hashCode

class MyObject3 {
    private String name;
    private int age;
    private int HASHCODE = Integer.MIN_VALUE;
    
    @Override
    public int hashCode() {
        if (HASHCODE == Integer.MIN_VALUE) {
            HASHCODE = name.hashCode() + String.valueOf(age).hashCode();
        }
        return HASHCODE;
    }
}

最佳實踐總結

  1. 不可變對象最安全:String、Integer 等不可變類型天然適合
  2. 必須重寫 equals/hashCode:且保持一致性
  3. 避免在集合中修改鍵屬性:或使用緩存 hashCode 模式
  4. 合理設計 hashCode 分佈:減少哈希衝突提升性能
  5. 考慮並發場景:使用 ConcurrentHashMap.newKeySet()
HashSet 內部結構
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved