Java 菜鳥教程

Java 流程控制

Java 數(shù)組

Java 面向?qū)ο?I)

Java 面向?qū)ο?II)

Java 面向?qū)ο?III)

Java 異常處理

Java 列表(List)

Java Queue(隊(duì)列)

Java Map集合

Java Set集合

Java 輸入輸出(I/O)

Java Reader/Writer

Java 其他主題

Java ConcurrentHashMap

在本教程中,我們將借助示例學(xué)習(xí)Java ConcurrentHashMap類及其操作。

Java集合框架的ConcurrentHashMap類提供了線程安全的映射。 也就是說,多個線程可以一次訪問該映射,而不會影響映射中條目的一致性。

它繼承了ConcurrentMap接口。

Java ConcurrentHashMap類實(shí)現(xiàn)ConcurrentMap接口。

創(chuàng)建一個ConcurrentHashMap

為了創(chuàng)建并發(fā)的哈希圖,我們必須先導(dǎo)入java.util.concurrent.ConcurrentHashMap包。導(dǎo)入包后,就可以在Java中創(chuàng)建并發(fā)哈希映射。

//ConcurrentHashMap具有容量8和負(fù)載因子0.6
ConcurrentHashMap<Key, Value> numbers = new ConcurrentHashMap<>(8, 0.6f);

在上面的代碼中,我們創(chuàng)建了一個名為numbers的并發(fā)哈希映射。

這里,

  • Key - 用于關(guān)聯(lián)map中每個元素(值)的唯一標(biāo)識符

  • Value - map中與鍵相關(guān)聯(lián)的元素

注意語句 new ConcurrentHashMap<>(8, 0.6)。在這里,第一個參數(shù)是capacity,第二個參數(shù)是loadFactor

  • capacity -該映射的容量為8。意味著,它可以存儲8個條目。

  • loadFactor-此map的負(fù)載因子為0.6。這意味著,只要我們的哈希表填充了60%,條目就會移到新哈希表中,其大小是原始哈希表的兩倍。

默認(rèn)容量和負(fù)載因子

無需定義其容量和負(fù)載因子就可以創(chuàng)建并發(fā)哈希圖。例如,

// 具有默認(rèn)容量和負(fù)載因子的ConcurrentHashMap
ConcurrentHashMap<Key, Value> numbers1 = new ConcurrentHashMap<>();

默認(rèn),

  • map的容量將為 16

  • 負(fù)載因子將為 0.75

從其他映射創(chuàng)建ConcurrentHashMap

這是我們?nèi)绾蝿?chuàng)建包含其他映射的所有元素的并發(fā)哈希映射。

import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;

class Main {
    public static void main(String[] args) {

        // 創(chuàng)建偶數(shù)的hashmap
        HashMap<String, Integer> evenNumbers = new HashMap<>();
        evenNumbers.put("Two", 2);
        evenNumbers.put("Four", 4);
        System.out.println("HashMap: " + evenNumbers);

        //從其他映射創(chuàng)建并發(fā)hashmap
        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>(evenNumbers);
        numbers.put("Three", 3);
        System.out.println("ConcurrentHashMap: " + numbers);
    }
}

輸出結(jié)果

HashMap: {Four=4, Two=2}
ConcurrentHashMap: {Four=4, Two=2, Three=3}

ConcurrentHashMap的方法

ConcurrentHashMap類提供了允許我們在映射上執(zhí)行各種操作的方法。

將元素插入ConcurrentHashMap

  • put() - 將指定的鍵/值映射插入到映射中

  • putAll() - 將指定映射的所有條目插入此map

  • putIfAbsent() - 如果映射中不存在指定的鍵,則將指定的鍵/值映射插入到map中

例如,

import java.util.concurrent.ConcurrentHashMap;

class Main {
    public static void main(String[] args) {
        //創(chuàng)建偶數(shù)的ConcurrentHashMap
        ConcurrentHashMap<String, Integer> evenNumbers = new ConcurrentHashMap<>();

        // 使用 put()
        evenNumbers.put("Two", 2);
        evenNumbers.put("Four", 4);

        // 使用 putIfAbsent()
        evenNumbers.putIfAbsent("Six", 6);
        System.out.println("偶數(shù)的ConcurrentHashMap: " + evenNumbers);

        //Creating ConcurrentHashMap of numbers
        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
        numbers.put("One", 1);

        // 使用 putAll()
        numbers.putAll(evenNumbers);
        System.out.println("ConcurrentHashMap的數(shù)字為: " + numbers);
    }
}

輸出結(jié)果

偶數(shù)的ConcurrentHashMap: {Six=6, Four=4, Two=2}
ConcurrentHashMap的數(shù)字為: {Six=6, One=1, Four=-4, Two=2}

訪問ConcurrentHashMap元素

1.使用entrySet(),keySet()和values()

  • entrySet() - 返回一組所有鍵/值映射的集合

  • keySet() - 返回map所有鍵的集合

  • values() - 返回map所有值的集合

例如,

import java.util.concurrent.ConcurrentHashMap;

class Main {
    public static void main(String[] args) {
        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();

        numbers.put("One", 1);
        numbers.put("Two", 2);
        numbers.put("Three", 3);
        System.out.println("ConcurrentHashMap: " + numbers);

        // 使用 entrySet()
        System.out.println("Key/Value 映射: " + numbers.entrySet());

        // 使用 keySet()
        System.out.println("Keys: " + numbers.keySet());

        // 使用 values()
        System.out.println("Values: " + numbers.values());
    }
}

輸出結(jié)果

ConcurrentHashMap: {One=1, Two=2, Three=3}
Key/Value 映射: [One=1, Two=2, Three=3]
Keys: [One, Two, Three]
Values: [1, 2, 3]

2.使用get()和getOrDefault()

  • get() - 返回與指定鍵關(guān)聯(lián)的值。如果找不到鍵,則返回null。

  • getOrDefault() - 返回與指定鍵關(guān)聯(lián)的值。如果找不到鍵,則返回指定的默認(rèn)值。

例如,

import java.util.concurrent.ConcurrentHashMap;

class Main {
    public static void main(String[] args) {

        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
        numbers.put("One", 1);
        numbers.put("Two", 2);
        numbers.put("Three", 3);
        System.out.println("ConcurrentHashMap: " + numbers);

        // 使用 get()
        int value1 = numbers.get("Three");
        System.out.println("使用get(): " + value1);

        // 使用 getOrDefault()
        int value2 = numbers.getOrDefault("Five", 5);
        System.out.println("使用getOrDefault(): " + value2);
    }
}

輸出結(jié)果

ConcurrentHashMap: {One=1, Two=2, Three=3}
使用get(): 3
使用getOrDefault(): 5

刪除ConcurrentHashMap元素

  • remove(key) - 返回并從映射中刪除與指定鍵關(guān)聯(lián)的條目

  • remove(key, value) - 僅當(dāng)指定鍵映射到指定值并返回布爾值時,才從映射中刪除條目

例如,

import java.util.concurrent.ConcurrentHashMap;

class Main {
    public static void main(String[] args) {

        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
        numbers.put("One", 1);
        numbers.put("Two", 2);
        numbers.put("Three", 3);
        System.out.println("ConcurrentHashMap: " + numbers);

        //單參數(shù)刪除方法
        int value = numbers.remove("Two");
        System.out.println("被刪除的值: " + value);

        // 具有兩個參數(shù)的刪除方法
        boolean result = numbers.remove("Three", 3);
        System.out.println("條目 {Three=3} 被刪除? " + result);

        System.out.println("更新后的ConcurrentHashMap: " + numbers);
    }
}

輸出結(jié)果

ConcurrentHashMap: {One=1, Two=2, Three=3}
被刪除的值: 2
條目 {Three=3} 被刪除? True
更新后的ConcurrentHashMap: {One=1}

ConcurrentHashMap的批量操作方法

ConcurrentHashMap類提供了可以安全地應(yīng)用于并行的map不同的批量操作方法。

1. forEach()方法

forEach()方法遍歷我們的條目并執(zhí)行指定的函數(shù)。

它包含兩個參數(shù)。

  • parallelismThreshold -它指定在映射中并行執(zhí)行多少個元素操作之后。

  • transformer -這將在將數(shù)據(jù)傳遞到指定函數(shù)之前轉(zhuǎn)換數(shù)據(jù)。

例如,

import java.util.concurrent.ConcurrentHashMap;

class Main {
    public static void main(String[] args) {

        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
        numbers.put("One", 1);
        numbers.put("Two", 2);
        numbers.put("Three", 3);
        System.out.println("ConcurrentHashMap: " + numbers);

        //forEach()不包含傳遞的函數(shù)
        numbers.forEach(4, (k, v) -> System.out.println("key: " + k + " value: " + v));

        // forEach()傳遞指定函數(shù)
        System.out.print("Values are ");
        numbers.forEach(4, (k, v) -> v, (v) -> System.out.print(v + ", "));
    }
}

輸出結(jié)果

ConcurrentHashMap: {One = 1, Two = 2, Three = 3}
key: One value: 1
key: Two value: 2
key: Three value: 3
Values are 1, 2, 3,

在上面的程序中,我們使用了并行閾值4。這意味著,如果映射包含4個條目,則該操作將并行執(zhí)行。

forEach()方法的變體

  • forEachEntry() - 為每個條目執(zhí)行指定的函數(shù)

  • forEachKey() - 為每個鍵執(zhí)行指定的函數(shù)

  • forEachValue() - 為每個值執(zhí)行指定的函數(shù)

2. search()方法

search()方法基于指定的函數(shù)搜索map并返回匹配的條目。

這里,指定的函數(shù)決定搜索什么條目。

它還包含一個可選參數(shù)parallelThreshold。并行閾值指定在映射中有多少元素之后并行執(zhí)行操作。

例如,

import java.util.concurrent.ConcurrentHashMap;

class Main {
    public static void main(String[] args) {

        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
        numbers.put("One", 1);
        numbers.put("Two", 2);
        numbers.put("Three", 3);
        System.out.println("ConcurrentHashMap: " + numbers);

        // 使用 search()
        String key = numbers.search(4, (k, v) -> {return v == 3 ? k: null;});
        System.out.println("被搜索的值: " + key);

    }
}

輸出結(jié)果

ConcurrentHashMap: {One=1, Two=2, Three=3}
被搜索的值: Three

search()方法的變體

  • searchEntries() - 搜索函數(shù)應(yīng)用于鍵/值映射

  • searchKeys() - 搜索函數(shù)僅適用于按鍵

  • searchValues() - 搜索函數(shù)僅應(yīng)用于值

3. reduce()方法

reduce()方法累積(聚集)映射中的每個條目。 當(dāng)我們需要所有條目來執(zhí)行一項(xiàng)常見任務(wù)(例如添加映射的所有值)時,可以使用此方法。

它包含兩個參數(shù)。

  • parallelismThreshold -它指定在有多少元素之后,map中的操作將并行執(zhí)行。

  • transformer - 這將在數(shù)據(jù)傳遞給指定函數(shù)之前對數(shù)據(jù)進(jìn)行轉(zhuǎn)換。

例如,

import java.util.concurrent.ConcurrentHashMap;

class Main {
    public static void main(String[] args) {

        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
        numbers.put("One", 1);
        numbers.put("Two", 2);
        numbers.put("Three", 3);
        System.out.println("ConcurrentHashMap: " + numbers);

        // 使用 search()
        int sum = numbers.reduce(4, (k, v) -> v, (v1, v2) -> v1 + v2);
        System.out.println("所有值的總和: " + sum);

    }
}

輸出結(jié)果

ConcurrentHashMap: {One=1, Two=2, Three=3}
所有值的總和: 6

在上面的程序中,請注意以下語句

numbers.reduce(4, (k, v) -> v, (v1, v2) -> v1+v2);

這里,

  • 4 是并行閾值

  • (k, v) -> v是一個轉(zhuǎn)換函數(shù)。它將鍵/值映射僅轉(zhuǎn)換為值。

  • (v1, v2) -> v1+v2 是計(jì)算大小函數(shù)。它收集所有值并將所有值相加。

reduce()方法的變體

  • reduceEntries() - 返回使用指定的reducer函數(shù)收集所有條目的結(jié)果

  • reduceKeys() - 返回使用指定的reducer函數(shù)收集所有鍵的結(jié)果

  • reduceValues() - 返回使用指定的reducer函數(shù)收集所有值的結(jié)果

ConcurrentHashMap和HashMap 的區(qū)別

以下是ConcurrentHashMap和HashMap之間的一些區(qū)別,

  • ConcurrentHashMap是線程安全的集合。也就是說,多個線程可以同時訪問和修改它。

  • ConcurrentHashMap提供用于批量操作的方法,例如forEach(),search()和reduce()。

為什么選擇ConcurrentHashMap?

  • ConcurrentHashMap類允許多個線程修改操作并發(fā)進(jìn)行。

  • 默認(rèn)情況下,并發(fā)哈希映射分為16段。這就是為什么允許16個線程同時修改映射的原因。但是,一次可以訪問任意數(shù)量的線程。

  • 如果指定的鍵已經(jīng)存在,則putIfAbsent()方法將不會覆蓋映射中的條目。

丰满人妻一级特黄a大片,午夜无码免费福利一级,欧美亚洲精品在线,国产婷婷成人久久Av免费高清