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étodoentrySet()
. 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.
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:-
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));
-
Utilize
SortedMap
, ou mais precisamente, sua implementaçãoTreeMap
, que leva um Comparator em seu construtor. Este comparador será aplicado às chaves do mapa, portanto as chaves devem ser classes que implementam a interfaceComparable
: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:-
Ordem dos elementos.
HashMap
eHashtable
nã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,TreeMap
garante o armazenamento dos elementos na ordem em que foram adicionados ou de acordo com um determinado comparador. -
Valores válidos.
HashMap
permite que você tenha uma chave e um valor nulo,HashTable
nã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. -
Sincronização. Apenas
HashTable
sincronizado, o resto não. Se o mapa não for acessado por threads diferentes, é recomendado usar HashMap em vez de HashTable.
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:-
Inicialização normal do objeto:
Map<Integer, String> emptyMap = new HashMap<>();
-
Criando um mapa vazio imutável:
Map<Integer, String> emptyMap = Collections.emptyMap();
UnsupportedOperationException
exceção. Neste artigo, analisamos as dúvidas mais comuns que você pode ter ao usar a interface do Mapa.
GO TO FULL VERSION