Entre para a LISTA VIP da Black Friday

00

DIAS

00

HORAS

00

MIN

00

SEG

Clique para saber mais

Iterando por um HashMap em Java

Iterando por um HashMap em Java
Imagem de destaque #cover

Estamos desenvolvendo um sistema web para uma empresa de ensino online. Nesse sistema é necessário que o usuário preencha um cadastro inicial, nada muito trabalhoso, apenas o nome, data de nascimento e o estado onde ele reside.

Temos o seguinte formulário de cadastro:

Mas se abrirmos a lista de opções de estados temos o seguinte resultado:

Ele está vazio. Não é isso que queremos. Queremos que quando o usuário abrir a lista de opções a mesma esteja preenchida com as siglas dos estados. Algo assim:

Temos um HashMap com as siglas e os estados e queremos usar para conseguir preencher nosso formulário. Esse HashMap foi feito através do seguinte método:


public HashMap<String, String> getMapa() { 
HashMap<String, String> map = new HashMap<>(); 
map.put("AC", "Acre"); map.put("AL", "Alagoas");
map.put("AP", "Amapá"); map.put("AM", "Amazonas");
map.put("BA", "Bahia"); map.put("CE", "Ceará"); 
map.put("DF", "Distrito Federal"); map.put("ES", "Espírito Santo"); 
map.put("GO", "Goiás"); 
//resto dos put() 
return map; }

Para conseguir retornar apenas as siglas, ou seja, as chaves, vamos usar o método keySet() da classe Map. Ele nos devolve um Set, que, basicamente, é uma coleção de elementos únicos, logo, não se repetem.

Agora vamos iterar sobre o retorno desse método para vermos se nosso método está realmente retornando todas as siglas:


HashMap<String, String> mapaEstados = getMapa(); 
for (String sigla : mapaEstados.keySet()) { System.out.print(sigla + " "); }

Ao executar esse código, obtemos o seguinte resultado:

Funcionou! Mas como faríamos para mostrar esse resultado na web?

Podemos usar uma JSP. Para conseguir o resultado esperado, só precisamos iterar os valores, desse jeito:

 <c:forEach items="${mapaEstados.keySet()}" 
 var="sigla"> <option>${sigla}</option> 
 </c:forEach>

E aí, visualizando o formulário:

Uma outra abordagem muito comum é o value da tag option ser a sigla, mas exibir o nome do estado por extenso. Ou seja, por exemplo, o value ser SP, só que o usuário veria São Paulo. Vamos tentar fazer isso?

Para alcançar tal resultado, precisamos tanto da chave quanto do valor do mapa. Para conseguirmos ambos, podemos usar o método entrySet() da classe Map. Ele nos devolve um Set<Map.Entry<K, V>>, onde K e V são os tipos da chave e do valor respectivamente do nosso mapa. Esse retorno nada mais é do que uma entrada contendo a chave e seu respectivo valor.

Vamos iterar esse entrySet():


for (Map.Entry<String, String> entrada : mapaEstados.entrySet()) {
     System.out.println(entrada); 
}

Como resultado desse código, temos o seguinte:

Mas perceba que essa forma não é ideal, pois não conseguimos manusear de forma eficaz a chave e o valor. Conseguimos, apenas, a entrada inteira e ainda com um sinal de igual horrível no meio. Para resolve isso, vamos usar os métodos getKey() e getValue() de Map.Entry:


HashMap<String, String> mapaEstados = getMapa(); 
for (Map.Entry<String, String> entrada : mapaEstados.entrySet()) { 
System.out.println(entrada.getKey()); 
System.out.println(entrada.getValue());
}

E como resultado, temos:

Cada chave está associada ao seu valor, está tudo correto. Agora, se fossemos implementar na JSP, teríamos que usar os métodos na JSP. Dessa forma:


<c:forEach items="${mapaEstados.entrySet()}" 
var="entrada"> <option value="${entrada.key}">${entrada.value}
</option> 
</c:forEach>

Se olharmos o código html, temos o seguinte: <select> <option value="RR">Boa Vista</option> <option value="RS">Porto Alegre</option><br /> <option value="DF">Brasília</option> //outros options </select>

Perceba que está exatamente do jeito que queríamos, o value é a sigla e para o usuário aparece os estados por extenso.

Se quiséssemos apenas os estados por extenso para o usuário escolher, sem precisar atribuir a chave como o value da tag option, poderíamos usar o método values() que retorna uma coleção contendo os valores do mapa. Assim:


HashMap<String, String> mapaEstados = getMapa();
 for (String valor : mapaEstados.values()) { 
     System.out.println(valor); 
}

Ao executar esse código:

Agora na JSP:


<c:forEach items="${mapaEstados.values()}" 
var="estado"> <option>${estado}</option> 
</c:forEach>

Voltando ao primeiro exemplo, caso nossa lista de estados contivesse apenas as siglas e, em outra tela, por exemplo uma tela de confirmação, onde mostrasse os dados que o usuário preencheu, quiséssemos mostrar o estado por extenso referente a sigla que o usuário escolheu, como faríamos?

Podemos criar um método que recebe como parâmetro a sigla escolhida e usar o método get() da interface Map para pegar seu respectivo valor. Dessa forma:


public static String pegaEstadoPorExtenso(String sigla){ 
HashMap<String, String> mapa = getMapa(); 
return mapa.get(sigla);
}

Para testarmos, vamos mandar a sigla RJ:


System.out.println(pegaEstadoPorExtenso("RJ"));

O resultado é exatamente o que esperamos:

Desenvolvemos tudo o que foi pedido de forma eficiente e limpa, parabéns!

Para saber mais

Todas as iterações que fizemos para testar nossos métodos poderiam ter sido feitas usando programação funcional, uma feature trazida com o Java 8. Por exemplo, para imprimir as siglas:


mapaEstados.keySet().stream().forEach(System.out::println);

Para imprimir as chaves e os valores:


mapaEstados.forEach((sigla, estado) -> System.out.println(sigla + " " + estado));

E por fim, os valores usando o values()


mapaEstados.values().stream().forEach(System.out::println);

Se quiser conhecer mais sobre as milhares de funcionalidades trazidas pelo Java 8 confira o curso Java 8: Tire proveito dos novos recursos da linguagem da Alura.

Quer dominar de vez mapas e coleções? Aqui na Alura temos uma formação em Java. Lá é mostrado a fundo cada coleção e, também, possui um capítulo só sobre mapas. Vale muito a pena dar uma conferida.

Veja outros artigos sobre Programação