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

Java HashMap 核心用法大全:統計、遍歷、排序與最佳實踐

     編輯:Java 綜合教學

Java HashMap 核心用法大全:統計、遍歷、排序與最佳實踐

HashMap 是 Java 集合框架中最高頻使用的鍵值存儲結構。本文匯總字符統計、多種遍歷方式、按 Value 排序等實戰場景,並解析底層原理與性能優化要點。

場景一:字符/單詞頻率統計

public class FrequencyCounter {
    public static void main(String[] args) {
        String text = "abcabcabcghgk";
        Map<Character, Integer> freqMap = new HashMap<>();

        for (char c : text.toCharArray()) {
            // Java 8+ merge 方法原子化更新,簡潔高效
            freqMap.merge(c, 1, Integer::sum);
        }

        // 輸出結果
        freqMap.forEach((k, v) -> System.out.println(k + " : " + v));
    }
}

/* 輸出:
a : 3
b : 3
c : 3
g : 2
h : 1
k : 1
*/

場景二:四種遍歷方式性能對比

方式 代碼示例 特點 推薦場景
EntrySet + 迭代器 for (Entry<K,V> e : map.entrySet()) 標準、可刪除、JDK 1.4+ 通用遍歷、需移除元素
KeySet + get for (K k : map.keySet()) map.get(k) 兩次查找、性能較差 僅需 Key 時
forEach (Java 8) map.forEach((k,v) -> ...) 函數式、不可刪除、可能較慢 簡單只讀操作
Stream API map.entrySet().stream()... 支持並行、鏈式操作 複雜篩選/轉換/聚合
// 安全刪除遍歷中的元素(避免 ConcurrentModificationException)
Iterator<Entry<K, V>> it = map.entrySet().iterator();
while (it.hasNext()) {
    Entry<K, V> entry = it.next();
    if (shouldRemove(entry)) {
        it.remove(); // 唯一安全的刪除方式
    }
}

場景三:按 Value 排序(Top N 需求)

推薦方案:TreeMap + 自定義 Comparator,或 Java 8 Stream 排序:

// 方案一:TreeMap + Comparator(穩定排序,保留鍵值關聯)
Map<String, Integer> countMap = new HashMap<>();
countMap.put("a", 10);
countMap.put("b", 20);
countMap.put("c", 5);

ValueComparator vc = new ValueComparator(countMap);
TreeMap<String, Integer> sortedMap = new TreeMap<>(vc);
sortedMap.putAll(countMap); // 按 Value 降序:b(20), a(10), c(5)

// Comparator 實現
class ValueComparator implements Comparator<String> {
    Map<String, Integer> base;
    public ValueComparator(Map<String, Integer> base) { this.base = base; }
    @Override
    public int compare(String a, String b) {
        // 降序:大的在前
        return base.get(b).compareTo(base.get(a));
        // 注意:返回 0 會導致鍵合併,需處理值相等情況
    }
}
// 方案二:Stream API(更現代、靈活、無需額外類)
List<Entry<String, Integer>> topList = countMap.entrySet().stream()
    .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
    .limit(10) // Top 10
    .collect(Collectors.toList());

topList.forEach(e -> System.out.println(e.getKey() + "=" + e.getValue()));

進階:HashMap 核心參數調優

參數 默認值 調優建議
初始容量 16 預估數據量 new HashMap<>(expectedSize),避免擴容
負載因子 0.75 時間換空間:降低(如 0.5)減少碰撞;空間換時間:提高(如 0.9)
樹化閾值 8 鏈表長度達 8 轉紅黑樹,防止哈希攻擊

常見坑點避雷

  • 鍵不可變:自定義 Key 必須正確重寫 hashCode() 和 equals(),且字段不可變(String/Integer/包裝類安全)。
  • 并發環境:多線程寫入必須用 ConcurrentHashMap,Collections.synchronizedMap 性能差。
  • 序列化陷阱:HashMap 實現 Serializable,但 transient 修飾的 table 字段需特殊處理。
  • 遍歷中修改:僅能通過 Iterator.remove() 或 computeIfPresent 等原子方法修改。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved