Java map: o que é e quais os métodos dessa interface?

Os conjuntos de dados do tipo map são também conhecidos por “arrays associativos”. São muito úteis durante o desenvolvimento de aplicações em Java quando precisamos pesquisar e atualizar elementos correspondentes com base em uma chave específica para determinado valor. Assim, o Java map “mapeia” os valores contidos no conjunto de dados tomando as chaves por referência, resumidamente.

Para muitas das pessoas iniciantes no mundo do desenvolvimento, pode parecer uma tarefa difícil estabelecer alguma relação entre esse conceito e o seu uso na linguagem Java. Se você é uma dessas pessoas, você está no lugar certo. Neste guia, exploraremos os principais detalhes dessa interface e como aplicá-la, usando vários exemplos práticos durante nossas explicações.

Entender bem sobre as principais interfaces da linguagem Java é de extrema importância para quem quer desenvolver boas aplicações, obedecendo às boas práticas e evitando muitos problemas desnecessários por falta do conhecimento de alguns detalhes. O Java map está entre essas interfaces, ocupando um espaço que merece a atenção de quem aspira à carreira do desenvolvimento. 

Por esse motivo, trazemos este guia até você. Nele, serão tratados diversos assuntos relevantes sobre o tema:

Tudo será explicado de maneira descomplicada, com uma teoria dinâmica percorrendo exemplos práticos e uso dos recursos apresentados. Acompanhe-nos em mais uma jornada pela linguagem Java!

O que é a interface Java map?

A Java map é uma das interfaces facilitadoras que estão disponíveis para serem usadas durante o desenvolvimento de aplicações em Java, por meio do pacote java.util. Sua função é facilitar a manipulação de uma estrutura de correspondência — ou seja, os conjuntos maps representam, sempre, uma chave e um valor correspondentes entre si:

fruta : cor
pera : amarela
maçã : vermelha
melancia : verde

O comportamento dessa interface difere das outras interfaces do framework Collections — o tipo map não possibilita o armazenamento de duas chaves idênticas. Apesar disso, é possível usar valores iguais entre as chaves, sem nenhum problema.

Diferentemente do que muitas pessoas iniciantes em Java podem pensar, a interface Map não é um uma das subinterfaces das coleções, como um List ou ArrayList. Na sequência, abordaremos mais sobre a hierarquia dessa estrutura.

Como funciona a hierarquia da interface Java map?

É possível implementarmos os conjuntos de dados de tipo map por meio de duas interfaces: Map e sortedMap (em que existe a ordenação dos elementos contidos nas chaves), usando suas três classes para ser implementada — HashMap(), LinkedHashMap() e TreeMap(). Cada uma delas carrega um detalhe específico e ocupa um modelo de implementação de um map de modos diferentes:

  • HashMap(): implementação de Map — é importante levar em consideração que o uso dessa classe não realiza a ordenação dos elementos;
  • LinkedHashMap(): a mesma coisa que a classe anterior, mas com ordenamento dos elementos contidos no map em ordem de inserção. Suporta o uso de valor e chaves nulos (“null”).
  • TreeMap(): o treeMap é implementação das interfaces Map e sortedMap — sempre usa a ordenação ascendente (do menor para o maior). É bastante usado na manipulação de dados hierárquicos e não tem suporte para uso de valores nulos (“null”).

Qual a sintaxe da interface Java map?

Como apenas pode haver uma chave específica para cada elemento em um map, é importante obedecermos a essa característica na hora que criarmos uma nova estrutura. Portanto, fazemos da seguinte forma:

Map<objeto_chave, objeto_valor> nome_do_mapa = new tipo_de_dado();

Repare que precisamos declarar o tipo de dado de cada objeto, seja no valor, seja na chave. Pense em uma situação em que temos nomes que precisamos relacionar com alguns números, como em uma agenda. Nesse caso, usamos as chaves para armazenar os nomes, e ela precisa ser única para cada posição.

Como são caracteres, definimos como String. Já no valor, como são números, precisamos declará-los com Inteiros (ou Integer). Confira o exemplo, com atenção especial a como realizamos a declaração do tipo de dados que queremos, pois será importante para a próxima parte do guia:

import java.util.HashMap;
import java.util.Map;

public class Main {

  public static void main(String[] args) 
   {

   Map<String, Integer> agenda = new HashMap<String, Integer>();
   agenda.put("Luma", 11222);
   agenda.put("Alex", 22333);
   agenda.put("Andrea", 3344);

   System.out.println(agenda);

  }
}

Pelo motivo de a interface map não ser instanciável, usamos a classe HashMap() para manipular o conjunto. A seguir, exploraremos mais dessa classe, com exemplos e detalhes sobre a implementação do Java map.

O que é HashMap()?

Falando de uma maneira bem resumida, o HashMap é a classe responsável por implementar uma estrutura map para a interface Map, armazenar chaves únicas (hashes) e as atribuir a valores. Embora possa parecer complicada de início, a sintaxe da interface e das classes usadas nos códigos são bem simples.

Para declararmos um novo map, podemos utilizar o HashMap. Para essa implementação, usaremos o “Map” + “nome que queremos para ele” e o igualaremos ao operador “new”, seguido do método HashMap(). Dessa maneira:

Map nomeDoMap = new HashMap();

Veja, a seguir, um exemplo prático em um código utilizando essa implementação:

import java.util.*;
 
public class Main {
   public static void main(String args[])
   {
       Map<String, String> meu_Map
           = new HashMap<String, String>();

       meu_Map.put("T", new String("melhor"));
       meu_Map.put("r", new String("escola"));
       meu_Map.put("y", new String("de"));
       meu_Map.put("b", new String("programação"));
       meu_Map.put("e", new String("e tecnologia"));

       for (Map.Entry<String, String> be :
            meu_Map.entrySet()) {

           System.out.print(be.getKey() + ":");
           System.out.println(be.getValue());
       }
   }
}

Caso ainda não tenha familiaridade com os métodos get(), set() e put(), não tem nenhum problema. Na sequência, abordaremos os principais detalhes desses recursos.

O que é Hashtable?

São também comumente conhecidas como “tabelas de dispersão”. É uma estrutura em forma de tabela, a qual é responsável por implementar um array abstrato e associá-lo a determinado tipo de estrutura de dado — realizando a correspondência das chaves com os valores contidos em um map, resumidamente.

A utilização mais comum das hashtables é a realização de buscas em estruturas map de maneira agilizada. É implementada por meio da função HashTable(), fazendo o uso de diferentes métodos para manipular seus elementos. A sintaxe utilizada na implementação é a mesma para o hashmap:

import java.util.*;  
   public class Hashtable_trybe{  
       public static void main(String args[]){  
        Hashtable<Integer,String> ht=new Hashtable<Integer,String>();  
     
        ht.put(100,"AAA");  
        ht.put(102,"BBB");  
        ht.put(101,"CCC");  
        ht.put(103,"DDD");  
     
      for(Map.Entry i:ht.entrySet()){  
      System.out.println(i.getKey()+" "+i.getValue());  
     }  
   }  
} 

Quais os métodos da interface Java map?

Assim como prometido, trazemos uma lista com os principais métodos utilizados na manipulação de um Map. Confira!

size()

Para usarmos o método size(), seguimos a seguinte sintaxe:

 Hash_Map.size(). 

Ele não recebe parâmetros — o método retorna o tamanho do map, ou seja, o número dos pares de chaves e valores contidos nele.

Exemplo de uso:

import java.util.*;
 
public class Main {
   public static void main(String[] args)
   {
       HashMap<Integer, String> H_map = new HashMap<Integer, String>();
 
       // Mapping string values to int keys
       H_map.put(0, "Venha");
       H_map.put(1, "com");
       H_map.put(2, "a");
       H_map.put(3, "Trybe");

       // Displaying the size of the map
       System.out.println("The size of the map is " + H_map.size());
   }
}

isEmpty()

O método boolean isEmpty() realiza uma verificação nas chaves e valores contidos no map para saber se está ou não vazio. Não usa argumentos, e retorna verdadeiro em caso de algum par chave-valor esteja vazio:

nome_map.isEmpty()

Exemplo de uso:

import java.util.*;
public class Main {
 
    public static void main(String[] args)
    {
        Map<String, String> novo_map = new HashMap<>();
        System.out.println(novo_map);
        System.out.println(novo_map.isEmpty());
    }
}

containsKey() e containsValue()

Os métodos containsKey() e containsValue() funcionam da mesma forma, mas um apenas para chaves e o outro somente para valores, respectivamente. A sintaxe é:

 Hash_Map.contains(Key ou Val)(elemento).

Os parâmetros necessários são a especificação do elemento a ser verificado, chaves ou valores. Retorna um dado booleano: verdadeiro, para os casos em que o elemento verificado esteja presente, e falso, para caso negativo.

Exemplo de uso:

import java.util.*;
 
public class Main {
    public static void main(String[] args)
    {
        HashMap<Integer, String> hash_map = new HashMap<Integer, String>();
        hash_map.put(0, "Estude");
        hash_map.put(1, "na");
        hash_map.put(2, "Trybe!");
        hash_map.put(3, "Be");
        hash_map.put(5, "Trybe");
 
        System.out.println("Elementos internos do map: " + hash_map);
 
        System.out.println("Verificar se a chave 0 existe " +
        hash_map.containsKey(0));
        
                System.out.println("Verificar se a chave 10 existe " +
        hash_map.containsKey(10));
 
        System.out.println("Verificar se a chave 2 existe: " +
        hash_map.containsValue(Be));
    } 
}

A saída será:

Elementos internos do map: {0=Estude, 1=na, 2=Trybe!, 3=Be, 5=Trybe}
Verificar se a chave 0 existe true
Verificar se a chave 10 existe false
Verificar se a chave 2 existe: true

get()

O método get() é usado para recuperar o elemento especificado no parâmetro que damos para ele. A sintaxe do get() é:

thisMap.get(objeto, chave_do_elemento)

O método retorna o valor contido na chave especificada.

Exemplo de uso:

import java.util.*;
 
public class Main {
    public static void main(String[] args)
    {
        Map<Integer, String> map = new HashMap<Integer, String>();
 
        map.put(0, "Aprenda");
        map.put(1, "com");
        map.put(2, "a");
        map.put(3, "Trybe");
 

        System.out.println("Elementos internos do map: " + map);
 

        System.out.println("Verificar a chave 0: " + map.get(0));
 
        System.out.println("Verificar a chave 5: " + map.get(5));
    }
}

put() e remove()

Put() e remove() são métodos responsáveis por colocar ou retirar elementos em uma estrutura map. Sua síntaxe é:

Hash_Map.put_ou_remove(key, val)

Não retorna valores, já que é responsável por inserir elementos.

Exemplo de uso:

import java.util.*;
 
public class HashMap{
    public static void main(String[] args)
    {
 
        HashMap<Integer, String> hmap = new HashMap<Integer, String>();
 
        hmap.put(0, "Estude");
        hmap.put(1, "com");
        hmap.put(2, "a");
        hmap.put(3, "Trybe!");
 
        System.out.println("O Map completo é: " + hmap);
        hmap.remove(2, "a");
        hmap.remove(3, "Trybe!");
        
        System.out.println("O Map depois do remove é: " + hmap);
        System.out.println("Agora, o map será: " + hmap);
    }
}

Fora esses, saiba que ainda existem alguns outros métodos que podem ser utilizados para implementar estruturas em map, como:

  • o forEach(), usado para iterar os valores e chaves da interface;
  • o replace(), utilizado para substituir elementos;
  • o merge(), operação funcional usada para mesclar diferentes maps, entre outros métodos.

O importante, agora, é entendermos o funcionamento e as possibilidades dessa estrutura para o desenvolvimento de aplicações em Java.

Operações funcionais na interface Java map!

Quando falamos sobre operações funcionais em Java map, estramos tratando daquelas funções em que podemos manipular estruturas de tipo map de maneira mais funcional. Nessas operações são usadas as expressões lambda como parâmetro.

Expressões lambda no Java também podem ser entendidas como se fossem um objeto, podendo ser executadas sob demanda. Foi implementada a partir do Java 8.

As principais operações funcionais que podem ser implementadas com a interface map são: compute(), computeIfAbsent() e computeIfPresent() — elas usam uma chave e uma expressão lambda como parâmetros. De modo geral, o método compute() funciona no cálculo do mapeamento de uma chave especificada e seu valor, se já estiver atualmente mapeado (usará o null, caso não exista).

A seguir, algumas aplicações do método compute() sendo utilizado em estruturas map como exemplos.

Exemplo 1 — map.compute

Mapeia a chave e seu valor atual — um exemplo de compute() incrementando um valor inteiro no map:

map.compute(key, (k, v) -> (v == null) ? 1 : v+1)

Exemplo 2 — map.computePresent

Mapeia chaves e valores, atualizando o valor especificado para a chave designada.

map.computePresent("100", (key, val) -> val == null ? null : value.toString().toUpperCase());

Exemplo 3 — map.computeIfAbsent

Calcula o valor de determinada chave usando dada função de mapeamento. Se a chave ainda não estiver associada a um valor (ou estiver mapeada para null), insere esse valor calculado no próprio Hashmap — ou o atualiza para “null”, caso não exista:

map.computeIfAbsent("123", (key) -> "abc");

Em todas essas situações, o valor retornado é inserido na chave da estrutura map. A chave é apagada em caso de retorno “null” da função.

Abordamos, durante o nosso guia, uma série de questões bastante relevantes para desenvolvimento de aplicações com o Java map, tanto no entendimento que a compreende como Interface quanto como estrutura de elementos de um conjunto. Com a leitura, você pode estabelecer sua definição de um ponto de vista bastante prático, explorando elementos de sua hierarquia e sintaxe.

Você viu alguns métodos utilizados para implementação, juntamente com alguns exemplos práticos sobre eles — com uma construção bastante didática. Com isso, obteve um aprofundamento sobre programação funcional com a utilização de alguns elementos presentes no Java map.

Trouxemos muitas novidades ao longo de nosso guia para que você possa colocar suas habilidades na linguagem Java em prática! Se você quer ir ainda mais longe e saber tudo sobre o assunto, que tal entrar em contato com a Trybe?

Podemos ajudar na sua entrada para o mercado de desenvolvimento, faça sua inscrição em nosso processo seletivo e se prepare.