中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java之HashMap的示例分析

發布時間:2021-08-11 09:35:12 來源:億速云 閱讀:119 作者:小新 欄目:開發技術

這篇文章主要介紹Java之HashMap的示例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

Java集合(Collections)框架中Map接口中HashMap的實現。Map雖然是Collctions框架的一部分,但是Map并沒有實現Collection接口,而Set和List是實現Collection接口的。

簡單來說,HashMap主要通過key存儲value值,并且提供了添加,獲取和操作存儲value的方法。HashMap的實現基于HashTable。

Java之HashMap的示例分析
HashMap內部呈現

Key-value對在內部是以buckets的方式存儲在一起,最終成為一個表。存儲和檢索操作的時間是固定的,也就是時間復雜度為O(1)。

這篇文章暫時不過于涉及HashMap的底層,我們先對HashMap有個整體認知。

put方法

Map中通過put方法來存儲一個value。

/**
     * 建立鍵值對應關系,如果之前已經存在對應的key,
     * 返回之前存儲的value,之前如果不存在對應的key,返回null
     */
    public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }

知識點一: 當Map的調用put方法的時候,key對象被調用hashCode()方法,獲得一個hash值供hashmap使用。
我們創建一個對象來證實一下。

public class MyKey {
    private int id;
    
    @Override
    public int hashCode() {
        System.out.println("調用 hashCode()");
        return id;
    }

    // constructor, setters and getters 
}

   @Test
    public void mapKeyTest(){
        HashMap<MyKey,String> map = new HashMap<MyKey, String>();
        String retV = map.put(new MyKey(1),"value1");
    }

可以看到控制臺的輸出信息

調用 hashCode()

知識點二: hash()方法計算出的hash值可以標識它在buckets數組中的索引位置。

HashMap的hash()方法如下:可以與put方法進行關聯。

static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

HashMap有一個特點,它可以存儲null的key和null的value。當key時null的時候,執行put方法,它會自動分配hash為0. 這也意味著key為null的時候沒有hash操作,這樣就避免了空指針異常。

get() 方法

為了獲取存儲在hashMap中的對象,我們需要知道與它對應的key。然后通過get方法把對應的key傳到參數里。調用HashMap的get方法的時候,也會調用key對象的hashCode方法

@Test
    public void mapKeyTest(){
        HashMap<MyKey,String> map = new HashMap<MyKey, String>();
        MyKey key1 = new MyKey(1);
        map.put(key1,"value1");
        String retV =  map.get(key1);
    }

控制臺上可以看到兩行輸出

調用 hashCode()
調用 hashCode()

HashMap中的集合視圖

HashMap提供了三種方式,讓我們可以把key和value作為其它集合來使用。

Set<K> keys = map.keySet()
Collection<V> values = map.values()
Set<Entry<K, V>> entries = map.entrySet();

注意: 在iteators創建完畢后,對map的任何結構修改,都會拋出一個異常。

@Test
public void givenIterator_whenFailsFastOnModification_thenCorrect() {
    Map<String, String> map = new HashMap<>();
    map.put("name", "baeldung");
    map.put("type", "blog");
 
    Set<String> keys = map.keySet();
    Iterator<String> it = keys.iterator();
    map.remove("type");
    while (it.hasNext()) {
        String key = it.next();
    }
}

// 會拋出java.util.ConcurrentModificationException異常

HashMap中唯一允許的修改是在iterator中移除元素。

public void givenIterator_whenRemoveWorks_thenCorrect() {
    Map<String, String> map = new HashMap<>();
    map.put("name", "baeldung");
    map.put("type", "blog");
 
    Set<String> keys = map.keySet();
    Iterator<String> it = keys.iterator();
 
    while (it.hasNext()) {
        it.next();
        it.remove();
    }
 
    assertEquals(0, map.size());
}

HashMap在iterator上的性能相比于LinkedHashMap和treeMap,性能非常糟糕。最差情況下為O(n),n為hashmap中條目的個數。

HashMap性能

HashMap的性能主要有兩個參數影響,初始容量和負載因子。初始容量為Map底層桶數組的長度,負載因子為當桶容量的長度為多大的時候,重新開辟新的空間。

int threshold;
    final float loadFactor;

默認的初始容量為16,默認的負載因子為0.75. 我們也可以自定義它們的值。

Map<String,String> hashMapWithCapacity=new HashMap<>(32);
Map<String,String> hashMapWithCapacityAndLF=new HashMap<>(32, 0.5f);

初始容量:

大的初始容量用于條目數較多,但是少量迭代(iteration)
小的初始容量用于條目數較少,但是多次迭代(iteration)

負載因子:
0.75是一個很折衷的方案了。在我們初始化HashMap的時候,初始容量和負載因子都應該考慮在內,比如為了減少重新hash的操作,初始容量乘以負載因子應該大于能存儲的最大條目數,這樣就不會發生重新hash的操作。

以上是“Java之HashMap的示例分析”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

廊坊市| 南和县| 罗田县| 凌源市| 汉川市| 凤凰县| 瓦房店市| 天镇县| 九江市| 安阳市| 彩票| 桃园县| 永年县| 宁夏| 淅川县| 遂平县| 焦作市| 常宁市| 黎平县| 桑日县| 沂南县| 昔阳县| 合阳县| 饶阳县| 班戈县| 龙门县| 视频| 罗城| 南雄市| 浠水县| 尉犁县| 江山市| 当涂县| 保定市| 建昌县| 梁山县| 神池县| 宜阳县| 青浦区| 库尔勒市| 汤阴县|