目錄
四.HashMap的简单应用
首頁 Java java教程 Java集合類別Hashmap的詳細介紹(程式碼範例)

Java集合類別Hashmap的詳細介紹(程式碼範例)

Feb 19, 2019 pm 01:33 PM
java

這篇文章帶給大家的內容是關於Java集合類別Hashmap的詳細介紹(程式碼範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

一.HashMap 簡介

HashMap在程式設計師的開發過程中是一個十分常用的集合類別,它是一個以鍵值對形式存在的集合類別,

在開發中我們可以利用的它的一個key存在即替換的特性,實現一個更新的去重的操作。

在另一個方便我們可以利用map跟fastJson快速組成我們所需的json資料格式。

在jdk1.8之前,HashMap是以數組鍊錶的形式存在,put進來的key的hashCode進過擾動函數計算後得到hash值,然後該值通過(n-1)&hash計算後的到對應的位置(n代表的是數組長度),

如果發生了hash衝突,則先判斷該key是否存在,如果存在那麼就覆蓋,否則以“拉鍊法”解決衝突,便組成了鍊錶。

但在jdk1.8之後,HashMap就發生了改變,如果當前鍊錶的長度大於閾值(預設是8)那麼該鍊錶就轉換成紅黑樹,加快了搜尋速度。

二.HashMap屬性

//HashMap預設的初始容量2^4=16
   static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

//HashMap的最大容量
   static final int MAXIMUM_CAPACITY = 1 << 30;##;預設的裝載因子當數組長度

   static final float DEFAULT_LOAD_FACTOR = 0.75f;


// 當桶(bucket)上的結點數大於這個值時會轉成紅黑樹

   statet int TREEIFY_THRESHOLD = 8;

##// 當桶(bucket)上的結點數小於這個值時樹轉鍊錶
   static final int UNTREEIFY_THRESHOLD = 6;

// 桶中結構轉換為紅黑樹對應的table的最小大小
   static final int MIN_TREEIFY_CAPACITY = 64;

// 儲存元素的數組,總是2的冪次倍數
   transient Nodek,v> ;[] table;

// 存放特定元素的集合
   transient Set> entrySet;

// 存放元素的數量,注意這個不等於數組的長度。
   transient int size;

// 每次擴容與改變map結構的計數器
   transient int modCount;

#// 臨界值當實際大小(容量*填充因子)超過臨界值時,會進行擴容(*當
size

大於等於

threshold的時候,並不一定會觸發擴容機制,但是會很可能就觸發擴容機制,只要有一個新建的Entry出現哈希衝突,則立刻resize    int threshold;// 填充因子 當Size>=threshold的時候,那麼就要考慮對陣列的擴增了,也就是說,這的意思就是 衡量陣列是否需要擴增的一個標準
   final float loadFactor;

三.HashMap的擴容機制

 public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);
        this.loadFactor = loadFactor;
        this.threshold = tableSizeFor(initialCapacity);
    }
登入後複製

 其中tableSizeFor這個程式碼是:

static final int tableSizeFor(int cap) {
        int n = cap - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }
登入後複製

>>>是無視符號位元的位元右移動符號  |= 是左右兩個數進行&運算

這個方法會把你傳進來的初始化容量變成一個是2的平方次方的數所以這裡就固定死了HashMap的容量必須是2的平方次方

#至於為什麼是2的平方次方的數原因如下:

1.put方法原始碼:

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;
        if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length;
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
        else {
            Node<K,V> e; K k;
            if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                e = p;
            else if (p instanceof TreeNode)
                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
            else {
                for (int binCount = 0; ; ++binCount) {
                    if ((e = p.next) == null) {
                        p.next = newNode(hash, key, value, null);
                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                            treeifyBin(tab, hash);
                        break;
                    }
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        break;
                    p = e;
                }
            }
            if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
                afterNodeAccess(e);
                return oldValue;
            }
        }
        ++modCount;
        if (++size > threshold)
            resize();
        afterNodeInsertion(evict);
        return null;
    }
登入後複製

看到其中 p = tab[i = (n - 1) & hash]) == null  這句話   (n - 1) & hash是計算到一個位置,如果這個tab中的位置是空的那麼直接做插入操作。

舉個欄位   假設有16個位置    有4位學生都有各自的學號

名稱#學號張三1李四2
#王五3
老李4


此时我们分配位置的时候可以采用 1%16 = 1;2%16=2;3%16 = 3;4%16=4;给他们分配位置,但是考虑到性能问题。由于%操作比&慢10倍左右,因此采用&运算会提高性能。

通过限制length是一个2的幂数, (n - 1) & hash和hash%n结果是一致的。这就是为什么要限制容量必须是一个2的幂的原因。

比如2的hashCode是2 那么它对应的二进制是 (0000 0010)

假设n=16

那么n-1=15对应的二进制是 1111 1111 & 0000 0010 = 1111 1111 = 0010 = 2

2%16=2

得到(n - 1) & hash和hash%n结果是一致的,考虑到性能所以每次的扩容都是以2的幂次方扩容。

四.HashMap的简单应用

public  static void mapMethod() {
		HashMap<String, Object> map = new HashMap<>();
		map.put("zhangsan", 11);
		map.put("lisi", 11);
		//重复key会覆盖
		map.put("zhangsan", 22);
		//便利
		for(String key:map.keySet()) {
			//根据key获取value
			System.out.println(key+"=======value:"+map.get(key));
		}
		//containsKey方法判断当前map是否包含该方法
		System.out.println(map.containsKey("zhangsan"));
		//size打印map的长度
		System.out.println(map.size());
		//移除key
		map.remove("zhangsan");
		//判断是否存在value
		System.out.println(map.containsValue("22"));
	}
登入後複製

以上是Java集合類別Hashmap的詳細介紹(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1672
14
CakePHP 教程
1428
52
Laravel 教程
1332
25
PHP教程
1276
29
C# 教程
1256
24
PHP與Python:了解差異 PHP與Python:了解差異 Apr 11, 2025 am 12:15 AM

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP:網絡開發的關鍵語言 PHP:網絡開發的關鍵語言 Apr 13, 2025 am 12:08 AM

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

突破或從Java 8流返回? 突破或從Java 8流返回? Feb 07, 2025 pm 12:09 PM

Java 8引入了Stream API,提供了一種強大且表達力豐富的處理數據集合的方式。然而,使用Stream時,一個常見問題是:如何從forEach操作中中斷或返回? 傳統循環允許提前中斷或返回,但Stream的forEach方法並不直接支持這種方式。本文將解釋原因,並探討在Stream處理系統中實現提前終止的替代方法。 延伸閱讀: Java Stream API改進 理解Stream forEach forEach方法是一個終端操作,它對Stream中的每個元素執行一個操作。它的設計意圖是處

PHP與其他語言:比較 PHP與其他語言:比較 Apr 13, 2025 am 12:19 AM

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP與Python:核心功能 PHP與Python:核心功能 Apr 13, 2025 am 12:16 AM

PHP和Python各有優勢,適合不同場景。 1.PHP適用於web開發,提供內置web服務器和豐富函數庫。 2.Python適合數據科學和機器學習,語法簡潔且有強大標準庫。選擇時應根據項目需求決定。

PHP的影響:網絡開發及以後 PHP的影響:網絡開發及以後 Apr 18, 2025 am 12:10 AM

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

PHP:許多網站的基礎 PHP:許多網站的基礎 Apr 13, 2025 am 12:07 AM

PHP成為許多網站首選技術棧的原因包括其易用性、強大社區支持和廣泛應用。 1)易於學習和使用,適合初學者。 2)擁有龐大的開發者社區,資源豐富。 3)廣泛應用於WordPress、Drupal等平台。 4)與Web服務器緊密集成,簡化開發部署。

PHP與Python:用例和應用程序 PHP與Python:用例和應用程序 Apr 17, 2025 am 12:23 AM

PHP適用於Web開發和內容管理系統,Python適合數據科學、機器學習和自動化腳本。 1.PHP在構建快速、可擴展的網站和應用程序方面表現出色,常用於WordPress等CMS。 2.Python在數據科學和機器學習領域表現卓越,擁有豐富的庫如NumPy和TensorFlow。

See all articles