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

HashSet vs HashMap 核心區別一覽:底層結構、去重邏輯、使用場景全對比

     編輯:Java 相關知識

核心區別表

維度HashSetHashMap
實現接口SetMap
存儲結構鍵值對,值固定為 PRESENT 對象鍵值對,鍵值任意
去重依據鍵(元素本身)鍵
允許 null單個 null 元素單個 null 鍵,多個 null 值
添加方法add(E e) → 返回 booleanput(K, V) → 返回舊值
遍歷方式Iterator / for-eachkeySet / entrySet / values
線程安全非安全非安全
典型場景去重集合、成員資格測試鍵值映射、緩存、索引

本質關係:HashSet 內部封裝 HashMap

public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, Serializable {
    private transient HashMap<E, Object> map;
    private static final Object PRESENT = new Object();

    public HashSet() { map = new HashMap<>(); }

    public boolean add(E e) { return map.put(e, PRESENT) == null; }
    public boolean contains(Object o) { return map.containsKey(o); }
    public boolean remove(Object o) { return map.remove(o) == PRESENT; }
    public Iterator<E> iterator() { return map.keySet().iterator(); }
    public int size() { return map.size(); }
    // ... 其他方法均委託 map
}

去重機制深度解析

兩者均依賴 hashCode() 定位桶位,equals() 比較鍵是否相等。

  • HashSet:元素即鍵,add(e) 時若鍵已存在(hashCode 相等且 equals 為 true),put 返回舊值非 null,add 返回 false → 去重成功。
  • HashMap:put(k, v) 若鍵已存在,覆蓋舊值並返回舊值;鍵不存在返回 null。

自定義對象作鍵/元素的鐵律

class Person {
    String name; int age;
    // 必須重寫 hashCode() 和 equals(),且保持一致
    @Override public boolean equals(Object o) { ... }
    @Override public int hashCode() { return Objects.hash(name, age); }
}

否則:HashSet 無法去重,HashMap 無法正確查找。

選型指南

  1. 需要唯一值集合、頻繁 contains 判斷 → HashSet
  2. 需要鍵值映射、按鍵取值、緩存 → HashMap
  3. 需要有序去重 → LinkedHashSet / LinkedHashMap
  4. 需要排序去重 → TreeSet / TreeMap
  5. 多線程環境 → Collections.synchronizedSet/Map 或 ConcurrentHashMap / CopyOnWriteArraySet

總結

HashSet 就是鍵為元素、值固定為 PRESENT 的 HashMap 封裝。理解這層關係,所有 API 行為(去重、遍歷、性能)自然通透。選型核心:集合用 Set,映射用 Map,不要為了去重硬用 Map,也不要為了存鍵值對硬用 Set。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved