English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Java 基礎教程

Controllo di流程 Java

Array Java

Java orientata agli oggetti (I)

Java orientata agli oggetti (II)

Java orientata agli oggetti (III)

Java 異常處理

List Java

Queue Java (coda)

Map collection Java

Set collection Java

Input/Output (I/O) Java

Reader/Writer Java

Altri argomenti Java

Java ConcurrentHashMap

In questo tutorial, impareremo tramite esempi la classe Java ConcurrentHashMap e le sue operazioni.

La classe ConcurrentHashMap del framework di collection Java fornisce una mappa sicura per i thread. Questo significa che più thread possono accedere contemporaneamente a questa mappa senza influenzare la coerenza degli elementi nella mappa.

EreditaInterfaccia ConcurrentMap.

Creare una ConcurrentHashMap

Per creare una mappa hash concorrente, dobbiamo prima importare il pacchetto java.util.concurrent.ConcurrentHashMap. Dopo aver importato il pacchetto, possiamo creare una mappa di mappature concorrenti in Java.

// ConcurrentHashMap con capacità 8 e fattore di carico 0.6
ConcurrentHashMap<Key, Value> numbers = new ConcurrentHashMap<>(8, 0.6f);

Nel codice sopra, abbiamo creato un ConcurrentHashMap chiamato numbers.

Qui,

  • Key - identificatore unico utilizzato per associare ogni elemento (valore) nella mappa

  • Value - elemento associato alla chiave nella mappa

Attenzione alla frase new ConcurrentHashMap<>(8, 0.6). Qui, il primo parametro ècapacity, il secondo parametro èloadFactor.

  • capacity - La capacità di questa mappa è 8. Questo significa che può memorizzare 8 elementi.

  • loadFactor- Il fattore di carico di questa mappa è 0.6. Questo significa che, una volta che la nostra tabella hash è riempita al 60%, gli elementi verranno spostati in una nuova tabella hash di due volte più grande.

Capacità e fattore di carico predefiniti

Non è necessario definire capacità e fattore di carico per creare un ConcurrentHashMap. Ad esempio,

// ConcurrentHashMap con capacità e fattore di carico predefiniti
ConcurrentHashMap<Key, Value> numbers1 = new ConcurrentHashMap<>();

Per default

  • La capacità della mappa sarà 16

  • Il fattore di carico sarà 0.75

Creazione di ConcurrentHashMap a partire da un'altra mappa

Ecco come possiamo creare un ConcurrentHashMap contenente tutti gli elementi di un'altra mappa.

import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
class Main {
    public static void main(String[] args) {
        // Creazione di una HashMap per numeri pari
        HashMap<String, Integer> evenNumbers = new HashMap<>();
        evenNumbers.put("Two", 2)
        evenNumbers.put("Four", 4)
        System.out.println("HashMap: " + evenNumbers);
        // Creazione di un ConcurrentHashMap a partire da un'altra mappa
        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>(evenNumbers);
        numbers.put("Three", 3);
        System.out.println("ConcurrentHashMap: " + numbers);
    }
}

Risultato di output

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

Metodi di ConcurrentHashMap

ConcurrentHashMap类提供了允许我们在映射上执行各种操作的方法。

将元素插入ConcurrentHashMap

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

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

  • putIfAbsent() - 如果映射中不存在指定的键,则将指定的键/值映射插入到map中

Ad esempio,

import java.util.concurrent.ConcurrentHashMap;
class Main {
    public static void main(String[] args) {
        //创建偶数的ConcurrentHashMap
        ConcurrentHashMap<String, Integer> evenNumbers = new ConcurrentHashMap<>();
        // 使用 put()
        evenNumbers.put("Two", 2)
        evenNumbers.put("Four", 4)
        // 使用 putIfAbsent()
        evenNumbers.putIfAbsent("Six", 6)
        System.out.println("偶数的ConcurrentHashMap: " + evenNumbers)
        //Creating ConcurrentHashMap of numbers
        ConcurrentHashMap<String, Integer> numbers = new ConcurrentHashMap<>();
        numbers.put("One", 1);
        // 使用 putAll()
        numbers.putAll(evenNumbers)
        System.out.println("ConcurrentHashMap的数字为: " + numbers)
    }
}

Risultato di output

偶数的ConcurrentHashMap: {Six=6, Four=4, Two=2}
ConcurrentHashMap的数字为: {Six=6, One=1, Four=-4, Two=2}

访问ConcurrentHashMap元素

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

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

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

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

Ad esempio,

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("Valori: " + numbers.values());
    }
}

Risultato di output

ConcurrentHashMap: {One=1, Two=2, Three=3}
Mappatura chiave/valore: [One=1, Two=2, Three=3]
Chiavi: [One, Two, Three]
Valori: [1, 2, 3]

2. Utilizzo di get() e getOrDefault()

  • get() - Restituisce il valore associato alla chiave specificata. Se la chiave non viene trovata, restituisce null.

  • getOrDefault() - Restituisce il valore associato alla chiave specificata. Se la chiave non viene trovata, restituisce il valore predefinito specificato.

Ad esempio,

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);
        // Utilizzo di get()
        int value1 = numbers.get("Three");
        System.out.println("Utilizzo di get(): " + value1);
        // Utilizzo di getOrDefault()
        int value2 = numbers.getOrDefault("Five", 5);
        System.out.println("Utilizzo di getOrDefault(): " + value2);
    }
}

Risultato di output

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

Rimozione degli elementi ConcurrentHashMap

  • remove(key) - Restituisce e rimuove l'elemento associato alla chiave specificata dalla mappa.

  • remove(key, value) - Rimuove l'elemento dalla mappa solo se la chiave specificata è mappata al valore specificato e restituisce un valore booleano.

Ad esempio,

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);
        // Metodo di rimozione con un parametro
        int value = numbers.remove("Two");
        System.out.println("Valore eliminato: " + value);
        // Metodo di rimozione con due parametri
        boolean result = numbers.remove("Three", 3);
        System.out.println("L'elemento {Three=3} è stato eliminato? " + result);
        System.out.println("ConcurrentHashMap aggiornato: " + numbers);
    }
}

Risultato di output

ConcurrentHashMap: {One=1, Two=2, Three=3}
Valore eliminato: 2
L'elemento {Three=3} è stato eliminato? True
ConcurrentHashMap aggiornato: {One=1}

Metodi di operazioni in batch di ConcurrentHashMap

La classe ConcurrentHashMap offre metodi di operazioni in batch sicuri per applicazioni parallele a map differenti.

1. forEach()方法

1. Metodo forEach()

Contiene due parametri.

  • Il metodo forEach() esplora le nostre voci e esegue la funzione specificata.

  • parallelismThreshold - Specifica dopo quanti elementi operazioni in parallelo devono essere eseguite nella mappatura.

Ad esempio,

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);
        transformer - Questo convertirà i dati prima di passarli alla funzione specificata.
        // Il metodo forEach() non contiene la funzione passata
        // Passaggio della funzione specificata a forEach()
        System.out.print("Values are ");
        numbers.forEach(4, (k, v) -> v, (v) -> System.out.print(v + ", "));
    }
}

Risultato di output

ConcurrentHashMap: {One = 1, Two = 2, Three = 3}
key: One value: 1
key: Two value: 2
key: Three value: 3
Valori sono 1, 2, 3,

Nel programma sopra, abbiamo utilizzato il valore di soglia parallelo4Questo significa che se la mappatura contiene 4 voci, l'operazione verrà eseguita in parallelo.

Variabili del metodo forEach()

  • forEachEntry() - Esegue la funzione specificata per ogni voce

  • forEachKey() - Esegue la funzione specificata per ogni chiave

  • forEachValue() - Esegue la funzione specificata per ogni valore

2. Metodo search()

Il metodo search() ricerca la mappa in base alla funzione specificata e restituisce l'elemento corrispondente.

Qui, la funzione specificata decide cosa cercare.

Inoltre, include un parametro opzionale parallelThreshold. Il valore di soglia parallelo specifica dopo quanti elementi nella mappatura eseguire l'operazione in parallelo.

Ad esempio,

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);
        // Utilizzare search()
        String key = numbers.search(4, (k, v) -> {return v == 3 ? k : null;});
        System.out.println("Il valore cercato: " + key);
    }
}

Risultato di output

ConcurrentHashMap: {One=1, Two=2, Three=3}
Il valore cercato: Three

Variabili della funzione search()

  • searchEntries() - La funzione di ricerca si applica alla mappatura chiave/valore

  • searchKeys() - La funzione di ricerca si applica solo alle chiavi

  • searchValues() - La funzione di ricerca si applica solo ai valori

3. Il metodo reduce()

Il metodo reduce() accumula (aggrega) ogni voce della mappa. Quando dobbiamo utilizzare tutte le voci della mappa per eseguire un compito comune (ad esempio sommare tutti i valori della mappa) possiamo utilizzare questo metodo.

Contiene due parametri.

  • parallelismThreshold - Specifica dopo quanti elementi le operazioni sulla mappa eseguiranno in parallelo.

  • transformer - Questo trasformerà i dati prima di passare a una funzione specificata.

Ad esempio,

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);
        // Utilizzare search()
        int sum = numbers.reduce(4, (k, v) -> v, (v1, v2) -> v1 + v2);
        System.out.println("Somma di tutti i valori: " + sum);
    }
}

Risultato di output

ConcurrentHashMap: {One=1, Two=2, Three=3}
Somma di tutti i valori: 6

Nella seguente programma, notare le seguenti istruzioni

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

Qui,

  • 4 è il valore di soglia parallelo

  • (k, v) -> v è una funzione di trasformazione. Trasforma la mappatura chiave/valore solo nei valori.

  • (v1, v2) -> v1+v2 è una funzione di calcolo della dimensione. Raccoglie tutti i valori e li somma.

Varianti del metodo reduce()

  • reduceEntries() - Restituisce il risultato di raccogliere tutti gli elementi della mappa utilizzando la funzione reducer specificata

  • reduceKeys() - Restituisce il risultato di raccogliere tutti gli elementi chiave utilizzando la funzione reducer specificata

  • reduceValues() - Restituisce il risultato di raccogliere tutti i valori utilizzando la funzione reducer specificata

Le differenze tra ConcurrentHashMap e HashMap

Di seguito sono riportate le differenze tra ConcurrentHashMap eHashMapalcune differenze tra

  • ConcurrentHashMap èThread-safeSet. Questo significa che più thread possono accedervi e modificarlo contemporaneamente.

  • ConcurrentHashMap fornisce metodi per operazioni batch, come forEach(), search() e reduce().

Perché scegliere ConcurrentHashMap?

  • La classe ConcurrentHashMap Java permette che le operazioni di modifica multiple vengano eseguite in modo concorrente.

  • Per impostazione predefinita, la mappa hash concorrente Java è divisa in16 sezioniEcco perché è permesso che 16 thread modificano contemporaneamente la mappa. Ma in una volta può accedere un numero qualsiasi di thread.

  • Se la chiave specificata esiste già, il metodo putIfAbsent() non coprirà l'elemento nella mappa.