JavaRush /Blogue Java /Random-PT /Respostas às perguntas mais populares sobre a interface d...

Respostas às perguntas mais populares sobre a interface do Mapa

Publicado no grupo Random-PT
Olá! Hoje daremos respostas para as dúvidas mais comuns sobre o Mapa, mas antes vamos relembrar o que é. Respostas às perguntas mais populares sobre a interface do Mapa - 1Um mapa é uma estrutura de dados que contém um conjunto de pares de valores-chave. Sua estrutura de dados lembra um dicionário, por isso é frequentemente chamada assim. Ao mesmo tempo, Map é uma interface e no jdk padrão contém as principais implementações: Hashmap, LinkedHashMap, Hashtable, TreeMap. A implementação mais utilizada é o Hashmap, por isso iremos utilizá-la em nossos exemplos. Esta é a aparência da criação e preenchimento padrão de um mapa:
Map<Integer, String> map = new HashMap<>();
map.put(1, "string 1");
map.put(2, "string 2");
map.put(3, "string 3");
E é assim que se obtém valores por chave:
String string1 = map.get(1);
String string2 = map.get(2);
String string3 = map.get(3);
Se tudo o que foi dito acima estiver claro, vamos prosseguir para nossas respostas às perguntas populares!

0. Como iterar todos os valores do mapa

Iterar sobre valores é a operação mais comum que você realiza com mapas. Todos os pares de valores-chave são armazenados na interface interna Map.Entry e, para obtê-los, você precisa chamar o método entrySet(). Ele retorna um conjunto de pares que podem ser repetidos:
for(Map.Entry<Integer, String> entry: map.entrySet()) {
   // get key
   Integer key = entry.getKey();
   // get value
   String value = entry.getValue();
}

Или используя итератор:
Iterator<Map.Entry<Integer, String>> itr = map.entrySet().iterator();
while(itr.hasNext()) {
   Map.Entry<Integer, String> entry =  itr.next();
   // get key
   Integer key = entry.getKey();
   // get value
   String value = entry.getValue();
}

1. Como converter mapa em lista

A interface Map possui 3 métodos que retornam uma lista de elementos:
  • keySet() - retorna um conjunto de chaves;
  • valores() - retorna uma coleção de valores;
  • entrySet() - retorna um conjunto de conjuntos de valores-chave.
Se você observar os construtores da classe ArrayList, notará que existe um construtor com um argumento do tipo Collection. Como Set é descendente de Collection, os resultados de todos os métodos acima podem ser passados ​​para o construtor da classe ArrayList. Então vamos criar novas listas e preenchê-las com valores de Map:
// key list
List<Integer> keyList = new ArrayList<>(map.keySet());
// value list
List<String> valueList = new ArrayList<>(map.values());
// key-value list
List<Map.Entry<Integer, String>> entryList = new ArrayList<>(map.entrySet());

2. Como classificar as chaves do mapa

A classificação de mapas também é uma operação bastante comum na programação. Você pode fazer isso de várias maneiras:
  1. Coloque Map.Entry em uma lista e classifique-a usando Comparator .

    No comparador compararemos apenas as chaves dos pares:

    List> list = new ArrayList(map.entrySet());
    Collections.sort(list, new Comparator<Map.Entry<Integer, String>>() {
       @Override
       public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
           return o1.getKey() - o2.getKey();
       }
    });
    

    Se você entende lambdas, esta entrada pode ser significativamente reduzida:

    Collections.sort(list, Comparator.comparingInt(Map.Entry::getKey));
  2. Utilize SortedMap, ou mais precisamente, sua implementação TreeMap, que leva um Comparator em seu construtor. Este comparador será aplicado às chaves do mapa, portanto as chaves devem ser classes que implementam a interface Comparable:

    SortedMap<Integer, String> sortedMap = new TreeMap<>(new Comparator<Integer>() {
       @Override
       public int compare(Integer o1, Integer o2) {
           return o1 - o2;
       }
    });

    E, claro, tudo pode ser reescrito usando lambdas:

    SortedMap<Integer, String> sortedMap = new TreeMap<>(Comparator.comparingInt(o -> o));

    Ao contrário do primeiro método, usando SortedMap, sempre armazenaremos os dados de forma ordenada.

3. Como classificar os valores do mapa

Aqui você deve usar uma abordagem semelhante à primeira para chaves - obtenha uma lista de valores e classifique-os na lista:
List <Map.Entry<Integer, String>> valuesList = new ArrayList(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<Integer, String>>() {
   @Override
   public int compare(Map.Entry<Integer, String> o1, Map.Entry<Integer, String> o2) {
       return o1.getValue().compareTo(o2.getValue());
   }
});
E o lambda para isso fica assim:
Collections.sort(list, Comparator.comparing(Map.Entry::getValue));

4. Qual é a diferença entre HashMap, TreeMap e Hashtable

Conforme mencionado anteriormente, existem 3 implementações principais da interface Map. Cada um deles possui características próprias:
  1. Ordem dos elementos. HashMape Hashtablenão garantem que os itens serão armazenados na ordem em que foram adicionados. Além disso, não garantem que a ordem dos elementos não mudará com o tempo. Por sua vez, TreeMapgarante o armazenamento dos elementos na ordem em que foram adicionados ou de acordo com um determinado comparador.

  2. Valores válidos. HashMappermite que você tenha uma chave e um valor nulo, HashTablenão. TreeMap só pode usar valores nulos se o comparador permitir. Sem usar um comparador (armazenando pares na ordem em que foram adicionados), nulo não é permitido.

  3. Sincronização. Apenas HashTablesincronizado, o resto não. Se o mapa não for acessado por threads diferentes, é recomendado usar HashMap em vez de HashTable.

E uma comparação geral de implementações:
HashMap Tabela Hash ÁrvoreMapa
Ordem dos elementos Não Não Sim
nulo como valor Sim Não Na verdade
Segurança do fio Não Sim Não
Complexidade algorítmica de busca de elementos O(1) O(1) O (log n)
Estrutura de dados nos bastidores tabela hash tabela hash árvore rubro-negra

5. Como criar um mapa bidirecional

Às vezes torna-se necessário utilizar uma estrutura de dados em que tanto as chaves quanto os valores sejam únicos, ou seja, o mapa conterá pares chave-chave. Esta estrutura de dados permite criar uma “visão/pesquisa invertida” no mapa. Ou seja, podemos encontrar uma chave pelo seu valor.Essa estrutura de dados é chamada de mapa bidirecional, que, infelizmente, não é suportada pelo JDK. Mas, felizmente, sua implementação pode ser encontrada nas bibliotecas Apache Common Collections ou Guava. Lá ele é chamado de BidiMap e BiMap, respectivamente. Estas implementações impõem restrições à exclusividade de chaves e valores. Isso cria um relacionamento um-para-um.

6. Como criar um mapa vazio

Existem duas maneiras de criar um mapa vazio:
  1. Inicialização normal do objeto:

    Map<Integer, String> emptyMap = new HashMap<>();
  2. Criando um mapa vazio imutável:

    Map<Integer, String> emptyMap =  Collections.emptyMap();
Quando tentamos adicionar dados a tal mapa, receberemos: UnsupportedOperationExceptionexceção. Neste artigo, analisamos as dúvidas mais comuns que você pode ter ao usar a interface do Mapa.
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION