HashMap <K, V> é uma parte da coleção Java desde Java 1.2. Esta classe é encontrada no pacote java.util . Ele fornece a implementação básica da interface Map do Java. Ele armazena os dados em pares (chave, valor) e você pode acessá-los por um índice de outro tipo (por exemplo, um inteiro). Um objeto é usado como uma chave (índice) para outro objeto (valor). Se você tentar inserir a chave duplicada, ela substituirá o elemento da chave correspondente.

HashMap é semelhante a HashTable , mas não está sincronizado. Ele permite armazenar as chaves nulas também, mas deve haver apenas um objeto de chave nula e pode haver qualquer número de valores nulos. Esta classe não oferece garantias quanto à ordem do mapa. Para usar essa classe e seus métodos, você precisa importar o pacote java.util.HashMap ou sua superclasse.

// Java program to illustrate HashMap class of java.util
// package
 
// Importing HashMap class
import java.util.HashMap;
 
// Main class
public class GFG {
 
    // Main driver method
    public static void main(String[] args)
    {
        // Create an empty hash map by declaring object
        // of string and integer type
        HashMap<String, Integer> map = new HashMap<>();
 
        // Adding elements to the Map
        // using standard add() method
        map.put("vishal", 10);
        map.put("sachin", 30);
        map.put("vaibhav", 20);
 
        // Print size and content of the Map
        System.out.println("Size of map is:- "
                           + map.size());
 
        // Printing elements in object of Map
        System.out.println(map);
 
        // Checking if a key is present and if
        // present, print value by passing
        // random element
        if (map.containsKey("vishal")) {
 
            // Mapping
            Integer a = map.get("vishal");
 
            // Printing value fr the corresponding key
            System.out.println("value for key"
                               + " \"vishal\" is:- " + a);
        }
    }
}
Saída
O tamanho do mapa é: - 3
{vaibhav = 20, vishal = 10, sachin = 30}
o valor da chave "vishal" é: - 10

 

A hierarquia do HashMap é a seguinte:

Hierarquia de HashMap em Java

 Sintaxe: Declaração

public class HashMap<K,V> extends AbstractMap<K,V>
                          implements Map<K,V>, Cloneable, Serializable

Parâmetros: leva dois parâmetros, a saber:

  • O tipo de chaves mantidas por este mapa
  • O tipo de valores mapeados

HashMap implementa interfaces Serializable , Cloneable , Map <K, V> . HashMap estende a classe AbstractMap <K, V> . As subclasses diretas são LinkedHashMap , PrinterStateReasons .

Os construtores no HashMap são os seguintes:

O HashMap fornece 4 construtores e o modificador de acesso de cada um é público, os quais são listados a seguir:

  1. HashMap()
  2. HashMap (int initialCapacity)
  3. HashMap (int initialCapacity, float loadFactor)
  4. HashMap (mapa do mapa)

Agora, discutindo os construtores acima, um por um, juntamente com a implementação dos mesmos com a ajuda de programas Java limpos.

Construtor 1: HashMap()

É o construtor padrão que cria uma instância de HashMap com uma capacidade inicial de 16 e fator de carga de 0,75.

Sintaxe:

HashMap<K, V> hm = new HashMap<K, V>();

Exemplo

// Java program to Demonstrate the HashMap() constructor
 
// Importing bsiic required classes
import java.io.*;
import java.util.*;
 
// Main class
// To add elements to HashMap
class GFG {
 
    // Main driver method
    public static void main(String args[])
    {
        // No need to mention the
        // Generic type twice
        HashMap<Integer, String> hm1 = new HashMap<>();
 
        // Initialization of a HashMap using Generics
        HashMap<Integer, String> hm2
            = new HashMap<Integer, String>();
 
        // Adding elements using put method
        // Custom input elements
        hm1.put(1, "one");
        hm1.put(2, "two");
        hm1.put(3, "three");
 
        hm2.put(4, "four");
        hm2.put(5, "five");
        hm2.put(6, "six");
 
        // Print and display mapping of HashMap 1
        System.out.println("Mappings of HashMap hm1 are : "
                           + hm1);
 
        // Print and display mapping of HashMap 2
        System.out.println("Mapping of HashMap hm2 are : "
                           + hm2);
    }
}
Saída
Os mapeamentos de HashMap hm1 são: {1 = um, 2 = dois, 3 = três}
Mapeamento de HashMap hm2 são: {4 = quatro, 5 = cinco, 6 = seis}

Construtor 2: HashMap (int initialCapacity)

Ele cria uma instância de HashMap com uma capacidade inicial especificada e fator de carga de 0,75.

Sintaxe:

HashMap<K, V> hm = new HashMap<K, V>(int initialCapacity);

Exemplo

// Java program to Demonstrate
// HashMap(int initialCapacity) Constructor
 
// Importing basic classes
import java.io.*;
import java.util.*;
 
// Main class
// To add elements to HashMap
class AddElementsToHashMap {
 
    // Main driver method
    public static void main(String args[])
    {
        // No need to mention the
        // Generic type twice
        HashMap<Integer, String> hm1 = new HashMap<>(10);
 
        // Initialization of a HashMap using Generics
        HashMap<Integer, String> hm2
            = new HashMap<Integer, String>(2);
 
        // Adding elements to object of HashMap
        // using put method
 
        // HashMap 1
        hm1.put(1, "one");
        hm1.put(2, "two");
        hm1.put(3, "three");
 
        // HashMap 2
        hm2.put(4, "four");
        hm2.put(5, "five");
        hm2.put(6, "six");
 
        // Printing elements of ahshMap 1
        System.out.println("Mappings of HashMap hm1 are : "
                           + hm1);
 
        // Printing elements of HashMap 2
        System.out.println("Mapping of HashMap hm2 are : "
                           + hm2);
    }
}
Saída
Os mapeamentos de HashMap hm1 são: {1 = um, 2 = dois, 3 = três}
Mapeamento de HashMap hm2 são: {4 = quatro, 5 = cinco, 6 = seis}

Construtor 3: HashMap (int initialCapacity, float loadFactor)

Ele cria uma instância de HashMap com uma capacidade inicial especificada e um fator de carga especificado.

Sintaxe:

HashMap<K, V> hm = new HashMap<K, V>(int initialCapacity, int  loadFactor);

Exemplo

// Java program to Demonstrate
// HashMap(int initialCapacity,float loadFactor) Constructor
 
// Importing basic classes
import java.io.*;
import java.util.*;
 
// Main class
// To add elements to HashMap
class GFG {
 
    // Main driver method
    public static void main(String args[])
    {
        // No need to mention the generic type twice
        HashMap<Integer, String> hm1
            = new HashMap<>(5, 0.75f);
 
        // Initialization of a HashMap using Generics
        HashMap<Integer, String> hm2
            = new HashMap<Integer, String>(3, 0.5f);
 
        // Add Elements using put() method
        // Custom input elements
        hm1.put(1, "one");
        hm1.put(2, "two");
        hm1.put(3, "three");
 
        hm2.put(4, "four");
        hm2.put(5, "five");
        hm2.put(6, "six");
 
        // Print and display elements in object of hashMap 1
        System.out.println("Mappings of HashMap hm1 are : "
                           + hm1);
 
        // Print and display elements in object of hashMap 1
        System.out.println("Mapping of HashMap hm2 are : "
                           + hm2);
    }
}
Saída
Os mapeamentos de HashMap hm1 são: {1 = um, 2 = dois, 3 = três}
Mapeamento de HashMap hm2 são: {4 = quatro, 5 = cinco, 6 = seis}

 4. HashMap (mapa do mapa): cria uma instância do HashMap com os mesmos mapeamentos do mapa especificado.

HashMap <K, V> hm = novo HashMap <K, V> (mapa do mapa);

// Java program to demonstrate the
// HashMap(Map map) Constructor
 
import java.io.*;
import java.util.*;
 
class AddElementsToHashMap {
    public static void main(String args[])
    {
        // No need to mention the
        // Generic type twice
        Map<Integer, String> hm1 = new HashMap<>();
 
        // Add Elements using put method
        hm1.put(1, "one");
        hm1.put(2, "two");
        hm1.put(3, "three");
 
        // Initialization of a HashMap
        // using Generics
        HashMap<Integer, String> hm2
            = new HashMap<Integer, String>(hm1);
 
        System.out.println("Mappings of HashMap hm1 are : "
                           + hm1);
       
        System.out.println("Mapping of HashMap hm2 are : "
                           + hm2);
    }
}
Saída
Os mapeamentos de HashMap hm1 são: {1 = um, 2 = dois, 3 = três}
Mapeamento de HashMap hm2 são: {1 = um, 2 = dois, 3 = três}

Executando várias operações no HashMap

1. Adicionando Elementos: Para adicionar um elemento ao mapa, podemos usar o método put() . No entanto, o pedido de inserção não é retido no Hashmap. Internamente, para cada elemento, um hash separado é gerado e os elementos são indexados com base nesse hash para torná-lo mais eficiente.

// Java program to add elements
// to the HashMap
 
import java.io.*;
import java.util.*;
 
class AddElementsToHashMap {
    public static void main(String args[])
    {
        // No need to mention the
        // Generic type twice
        HashMap<Integer, String> hm1 = new HashMap<>();
 
        // Initialization of a HashMap
        // using Generics
        HashMap<Integer, String> hm2
            = new HashMap<Integer, String>();
 
        // Add Elements using put method
        hm1.put(1, "Geeks");
        hm1.put(2, "For");
        hm1.put(3, "Geeks");
 
        hm2.put(1, "Geeks");
        hm2.put(2, "For");
        hm2.put(3, "Geeks");
 
        System.out.println("Mappings of HashMap hm1 are : "
                           + hm1);
        System.out.println("Mapping of HashMap hm2 are : "
                           + hm2);
    }
}
Saída
Os mapeamentos de HashMap hm1 são: {1 = Geeks, 2 = For, 3 = Geeks}
Mapeamento de HashMap hm2 são: {1 = Geeks, 2 = For, 3 = Geeks}

2. Mudando os Elementos: Depois de adicionar os elementos, se desejarmos mudar o elemento, isso pode ser feito adicionando novamente o elemento com o método put() . Uma vez que os elementos no mapa são indexados usando as chaves, o valor da chave pode ser alterado simplesmente inserindo o valor atualizado para a chave que desejamos alterar.

// Java program to change
// elements of HashMap
 
import java.io.*;
import java.util.*;
class ChangeElementsOfHashMap {
    public static void main(String args[])
    {
 
        // Initialization of a HashMap
        HashMap<Integer, String> hm
            = new HashMap<Integer, String>();
 
        // Change Value using put method
        hm.put(1, "Geeks");
        hm.put(2, "Geeks");
        hm.put(3, "Geeks");
 
        System.out.println("Initial Map " + hm);
 
        hm.put(2, "For");
 
        System.out.println("Updated Map " + hm);
    }
}
Saída

Mapa inicial {1 = Geeks, 2 = Geeks, 3 = Geeks}
Mapa atualizado {1 = Geeks, 2 = For, 3 = Geeks}

3. Removendo Elemento: Para remover um elemento do Mapa, podemos usar o método remove() . Este método pega o valor da chave e remove o mapeamento de uma chave deste mapa, se estiver presente no mapa.

// Java program to remove
// elements from HashMap
 
import java.io.*;
import java.util.*;
class RemoveElementsOfHashMap{
    public static void main(String args[])
    {
        // Initialization of a HashMap
        Map<Integer, String> hm
            = new HashMap<Integer, String>();
 
        // Add elements using put method
        hm.put(1, "Geeks");
        hm.put(2, "For");
        hm.put(3, "Geeks");
        hm.put(4, "For");
 
        // Initial HashMap
        System.out.println("Mappings of HashMap are : "
                           + hm);
 
        // remove element with a key
        // using remove method
        hm.remove(4);
 
        // Final HashMap
        System.out.println("Mappings after removal are : "
                           + hm);
    }
}

 
 

Saída
Os mapeamentos de HashMap são: {1 = Geeks, 2 = For, 3 = Geeks, 4 = For}
Os mapeamentos após a remoção são: {1 = Geeks, 2 = For, 3 = Geeks}

4. Traversal de HashMap

Podemos usar a interface Iterator para percorrer qualquer estrutura do Collection Framework. Como os Iteradores trabalham com um tipo de dados, usamos Entry <? ,? > para resolver os dois tipos separados em um formato compatível. Então, usando o método next(), imprimimos as entradas de HashMap.

// Java program to traversal a
// Java.util.HashMap
 
import java.util.HashMap;
import java.util.Map;
 
public class TraversalTheHashMap {
    public static void main(String[] args)
    {
        // initialize a HashMap
        HashMap<String, Integer> map = new HashMap<>();
 
        // Add elements using put method
        map.put("vishal", 10);
        map.put("sachin", 30);
        map.put("vaibhav", 20);
 
        // Iterate the map using
        // for-each loop
        for (Map.Entry<String, Integer> e : map.entrySet())
            System.out.println("Key: " + e.getKey()
                               + " Value: " + e.getValue());
    }
}

 
 

Saída
Chave: valor vaibhav: 20
Chave: Vishal Valor: 10
Chave: valor sachin: 30

Recursos importantes do HashMap

Para acessar um valor, é preciso conhecer sua chave. HashMap é conhecido como HashMap porque usa uma técnica chamada Hashing. Hashing é uma técnica de converter uma string grande em uma string pequena que representa a mesma string. Um valor mais curto ajuda na indexação e pesquisas mais rápidas. O HashSet também usa o HashMap internamente.
Alguns recursos importantes do HashMap são: 

  • HashMap é uma parte do pacote java.util.
  • HashMap estende uma classe abstrata AbstractMap que também fornece uma implementação incompleta da interface Map.
  • Ele também implementa interfaces clonáveis e serializáveis . K e V na definição acima representam Chave e Valor, respectivamente.
  • HashMap não permite chaves duplicadas, mas permite valores duplicados. Isso significa que uma única chave não pode conter mais de 1 valor, mas mais de 1 chave pode conter um único valor.
  • O HashMap permite a chave nula também, mas apenas uma vez e vários valores nulos.
  • Essa classe não oferece garantias quanto à ordem do mapa; em particular, não garante que o pedido permanecerá constante ao longo do tempo. É mais ou menos semelhante a HashTable, mas não está sincronizado.

 Estrutura Interna do HashMap

Internamente, o HashMap contém uma matriz de Nó e um nó é representado como uma classe que contém 4 campos: 

  1. hash int
  2. Tecla K
  3. Valor V
  4. Nó próximo

Pode-se observar que o nó contém uma referência ao seu próprio objeto. Portanto, é uma lista vinculada. 

HashMap: 
 

variedade

Nó: 
 

node_hash_map

Desempenho do HashMap

O desempenho do HashMap depende de 2 parâmetros que são nomeados da seguinte forma:

  1. Capacidade Inicial
  2. Fator de carga

1. Capacidade inicial - é a capacidade do HashMap no momento de sua criação (é o número de depósitos que um HashMap pode conter quando o HashMap é instanciado). Em java, é 2 ^ 4 = 16 inicialmente, o que significa que pode conter 16 pares de valores-chave.

2. Fator de carga - é o valor percentual da capacidade após o qual a capacidade do Hashmap deve ser aumentada (é a porcentagem de preenchimento dos depósitos após o qual ocorre o Rehashing). Em java, é 0.75f ​​por padrão, o que significa que o novo hashing ocorre após preencher 75% da capacidade.

3. Limiar - É o produto do Fator de Carga e da Capacidade Inicial. Em java, por padrão, é (16 * 0,75 = 12). Ou seja, o Rehashing ocorre após a inserção de 12 pares de valores-chave no HashMap.

4. Rehashing - É o processo de dobrar a capacidade do HashMap após atingir seu Limiar. Em java, o HashMap continua a refazer o hash (por padrão) na seguinte sequência - 2 ^ 4, 2 ^ 5, 2 ^ 6, 2 ^ 7,…. em breve. 
 

Se a capacidade inicial for mantida alta, o novo hashing nunca será feito. Mas, ao mantê-lo mais alto, aumenta a complexidade do tempo da iteração. Portanto, deve ser escolhido com muita habilidade para aumentar o desempenho. O número esperado de valores deve ser levado em consideração para definir a capacidade inicial. O valor do fator de carga mais geralmente preferido é 0,75, o que fornece uma boa relação entre os custos de tempo e espaço. O valor do fator de carga varia entre 0 e 1. 

Nota: A partir do Java 8 em diante, o Java começou a usar o Self Balancing BST em vez de uma lista vinculada para encadeamento. A vantagem do bst com autobalanceamento é que obtemos o pior caso (quando todas as teclas são mapeadas para o mesmo slot), o tempo de pesquisa é O (Log n). 
 

HashMap sincronizado

Como é dito que o HashMap não está sincronizado, ou seja, vários threads podem acessá-lo simultaneamente. Se vários threads acessam essa classe simultaneamente e pelo menos um thread a manipula estruturalmente, é necessário sincronizá-la externamente. Isso é feito sincronizando algum objeto que encapsula o mapa. Se esse objeto não existir, ele pode ser agrupado em Collections.synchronizedMap() para tornar o HashMap sincronizado e evitar o acesso não sincronizado acidental. Como no exemplo a seguir: 
 

Map m = Collections.synchronizedMap(new HashMap(...));

Agora o Mapa m está sincronizado. Os iteradores desta classe são rápidos para falhas se qualquer modificação da estrutura for feita após a criação do iterador, de qualquer forma, exceto por meio do método remove do iterador. Em uma falha do iterador, ele lançará ConcurrentModificationException.
 
Complexidade de tempo do HashMap: o HashMap fornece complexidade de tempo constante para operações básicas, obtenha e coloque se a função hash está gravada corretamente e dispersa os elementos adequadamente entre os baldes. A iteração no HashMap depende da capacidade do HashMap e de vários pares de valores-chave. Basicamente, é diretamente proporcional à capacidade + tamanho. A capacidade é o número de depósitos no HashMap. Portanto, não é uma boa ideia manter um grande número de depósitos no HashMap inicialmente.
 
Aplicações de HashMap:HashMap é principalmente a implementação de hashing. É útil quando precisamos de uma implementação eficiente de operações de pesquisa, inserção e exclusão. Consulte os aplicativos de hashing para obter detalhes.

Métodos em HashMap

  • K - o tipo das chaves no mapa.
  • V - Tipo de valores mapeados no mapa.

MÉTODO

DESCRIÇÃO

Claro()Remove todos os mapeamentos deste mapa.
clone()Retorna uma cópia superficial desta instância de HashMap: as chaves e os valores em si não são clonados.
compute (tecla K, BiFunção <? super K ,? super V ,? extends V> remapeamentoFunção)Tenta calcular um mapeamento para a chave especificada e seu valor mapeado atual (ou nulo se não houver mapeamento atual).
computeIfAbsent (tecla K, Função <? super K ,? extends V> mappingFunction)Se a chave especificada ainda não estiver associada a um valor (ou estiver mapeada para nulo), tenta calcular seu valor usando a função de mapeamento fornecida e o insere neste mapa, a menos que seja nulo. 
computeIfPresent (K key, BiFunction <? super K ,? super V ,? extends V> remappingFunction)Se o valor da chave especificada estiver presente e não for nulo, tenta calcular um novo mapeamento, dada a chave e seu valor mapeado atual. 
containsKey (chave do objeto)Retorna verdadeiro se este mapa contém um mapeamento para a chave especificada.
containsValue (valor do objeto)Retorna verdadeiro se este mapa mapeia uma ou mais chaves para o valor especificado.
entrySet()Retorna uma visualização Set dos mapeamentos contidos neste mapa.
get (chave do objeto)Retorna o valor para o qual a chave especificada é mapeada ou nulo se este mapa não contém mapeamento para a chave.
está vazia()Retorna verdadeiro se este mapa não contém mapeamentos de valores-chave.
conjunto de chaves()Retorna uma visualização Set das chaves contidas neste mapa.
mesclar (tecla K, valor V, BiFunção < ? super V,? super V ,? estende V> função remapeamento)Se a chave especificada ainda não estiver associada a um valor ou estiver associada a nulo, associa-a ao valor não nulo fornecido.
colocar (chave K, valor V)Associa o valor especificado à chave especificada neste mapa.
putAll (Map <? estende K ,? estende V> m)Copia todos os mapeamentos do mapa especificado para este mapa.
remover (chave do objeto)Remove o mapeamento para a chave especificada deste mapa, se presente.
Tamanho()Retorna o número de mapeamentos de valores-chave neste mapa.
valores()Retorna uma visualização de Coleção dos valores contidos neste mapa.

 Métodos herdados da classe java.util.AbstractMap

MÉTODO

DESCRIÇÃO

é igual a()Compara o objeto especificado com este mapa para igualdade.
hashCode()Retorna o valor do código hash para este mapa.
para sequenciar()Retorna uma representação de string deste mapa.

Métodos herdados da interface java.util.Map

MÉTODO

DESCRIÇÃO



é igual a()Compara o objeto especificado com este mapa para igualdade.

forEach (BiConsumer <? super K,

? super V> ação)

Executa a ação fornecida para cada entrada neste mapa até que todas as entradas tenham sido processadas ou a ação lance uma exceção. 
getOrDefault (chave do objeto, V defaultValue)Retorna o valor para o qual a chave especificada é mapeada ou defaultValue se este mapa não contiver mapeamento para a chave.
hashCode()Retorna o valor do código hash para este mapa.
putIfAbsent (chave K, valor V)Se a chave especificada ainda não estiver associada a um valor (ou estiver mapeada para nulo), a associa ao valor fornecido e retorna nulo, caso contrário, retorna o valor atual.
remove (chave do objeto, valor do objeto)Remove a entrada para a chave especificada apenas se ela estiver atualmente mapeada para o valor especificado.
substituir (chave K, valor V)Substitui a entrada da chave especificada apenas se ela estiver mapeada para algum valor.
substituir (chave K, V antigoValor, V novoValor)Substitui a entrada da chave especificada apenas se atualmente mapeada para o valor especificado.

replaceAll (BiFunction <? super K,

? super V ,? estende V> função)

Substitui o valor de cada entrada com o resultado de invocar a função fornecida nessa entrada até que todas as entradas tenham sido processadas ou a função lance uma exceção.

Deve ler:

Este artigo foi contribuído por Vishal Garg . Se você gosta de GeeksforGeeks e gostaria de contribuir, você também pode escrever um artigo usando write.geeksforgeeks.org ou enviar seu artigo para review-team@geeksforgeeks.org. Veja o seu artigo na página principal do GeeksforGeeks e ajude outros Geeks. Escreva comentários se encontrar algo incorreto ou se quiser compartilhar mais informações sobre o tópico discutido acima.