Pessoal, boa noite!
Estou com uma duvida em relação a listagem do HashMap, segue o codigo, consigo adicionar e remover:
import java.util.*;
public class HashMaap implements Agenda {
private Map<Contato,String> contatos = new HashMap<>();
public boolean adicionar(String nome, String telefone){
Contato contato = new Contato(nome);
for(Contato c : this.contatos.keySet()){
contatos.containsKey(telefone);
contatos.containsValue(nome);
if(c.equals(contato)){
return contatos != null;
}
}
return contato.getTelefone().add(telefone);
}
public boolean remover(String nome, String telefone){
Contato c = new Contato(nome);
for(Contato i: this.contatos.keySet()){
if(i.equals(c)){
i.getTelefone().remove(telefone);
if(i.getTelefone().isEmpty()){
this.contatos.remove(i);
}
}
}
return false;
}
public Collection<Contato> getContatos(){
return (Collection<Contato>) this.contatos;
}
}
Alguem poderia dizer o que está errado?
Qual é a mensagem de erro que aparece? Qual o problema/erro?
Aparece a seguinte mensagem:
Exception in thread “main” java.lang.ClassCastException: java.util.HashMap cannot be cast to java.util.Collection
at parcialAgenda.HashMaap.getContatos(HashMaap.java:35)
at parcialAgenda.AppAgenda.listar(AppAgenda.java:64)
at parcialAgenda.AppAgenda.main(AppAgenda.java:26)
Mike
Junho 15, 2018, 11:52am
#5
Você esta tentando converter HashMap pra Collection, a pergunta é, pq?
O que você esta colocando no valor do map?
Qual seria a melhor forma de listar?
Mike
Junho 15, 2018, 11:56am
#7
Da até para diminuir o método abaixo usando lambda do java 8
Map<String, String> map = new HashMap<>();
...
for(Map.Entry<String, String> entry :map.entrySet())
{
System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
}
Map trabalha com chave e valor
Através de uma chave encontramos o seu valor, normalmente um id/código ou algo que seja único, que não vá se repetir nos outros objetos.
Você fez um cenário que é raro encontrar, esta utilizando a classe Contato como chave para chegar a um valor String, por isso lhe pergunto de novo, o que seria a sua String que esta no map?
Segue todas minhas classes, estava com ArrayList mas gostaria de mudar para HashMap
package parcialAgenda;
import java.util.Collection;
public interface Agenda {
public boolean adicionar (String nome, String telefone);
public boolean remover (String nome, String telefone);
public Collection<Contato> getContatos();
}
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.HashMap;
import java.util.Map;
public class Contato {
private String nome;
private Set<String> telefone;
public Contato(String nome) {
this.nome = nome;
this.telefone = new HashSet<>();
}
//Gerar os gets e sets, equals e HashCode
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public Set<String> getTelefone(){
return telefone;
}
public int hashCode() {
return this.nome.hashCode();
}
public boolean equals (Object obj) {
if (this==obj) {
return true;
}
if (obj==null) {
return false;
}
if (getClass()!=obj.getClass()) {
return false;
}
final Contato other = (Contato) obj;
if(!Objects.equals(this.nome, other.nome)) {
return false;
}
return true;
}
}
package parcialAgenda;
import java.util.Scanner;
public class AppAgenda {
private static Agenda agenda = new HashMaap();
public static void main(String[] args) {
Scanner teclado = new Scanner (System.in);
int opcao = 0;
do {
System.out.println("####Aplicativo Agenda####");
System.out.println("1 - Adicionar um telefone");
System.out.println("2 - Remover um telefone");
System.out.println("3 - Listar contatos");
System.out.println("4 - Sair");
opcao = Integer.valueOf(teclado.nextLine());
switch (opcao) {
case 1: adicionar(teclado); break;
case 2: remover(teclado); break;
case 3: listar(); break;
}
}while (opcao != 4);
teclado.close();
}
public static void adicionar (Scanner teclado) {
System.out.println("Informe o nome do contato: ");
String nome = teclado.nextLine();
System.out.println("Informe o novo telefone");
String telefone = teclado.nextLine();
if (agenda.adicionar(nome, telefone)) {
System.out.println("Adicionado com Sucesso!");
}else {
System.out.println("Telefone já existe!");
}
}
public static void remover (Scanner teclado) {
System.out.println("Informe o nome do contato: ");
String nome = teclado.nextLine();
System.out.println("Informe o telefone do contato: ");
String telefone = teclado.nextLine();
if(agenda.remover(nome, telefone)) {
System.out.println("Removido com sucesso!");
}else {
System.out.println("Contato/Telefone não existem!");
}
}
public static void listar() {
for (Contato c: agenda.getContatos()) {
System.out.println(c.getNome()+": "+c.getTelefone());
}
}
}
package parcialAgenda;
import java.util.*;
public class HashMaap implements Agenda {
private Map<Contato,String> contatos = new HashMap<>();
public boolean adicionar(String nome, String telefone){
Contato contato = new Contato(nome);
for(Contato c : this.contatos.keySet()){
contatos.containsKey(telefone);
contatos.containsValue(nome);
if(c.equals(contato)){
return contatos != null;
}
}
return contato.getTelefone().add(telefone);
}
public boolean remover(String nome, String telefone){
Contato c = new Contato(nome);
for(Contato i: this.contatos.keySet()){
if(i.equals(c)){
i.getTelefone().remove(telefone);
if(i.getTelefone().isEmpty()){
this.contatos.remove(i);
}
}
}
return false;
}
public Collection<Contato> getContatos(){
return (Collection<Contato>) this.contatos;
}
}
Mike
Junho 15, 2018, 12:13pm
#9
Você tentou o código que postei?
Se sim, colocou ele a onde?
limassa
Junho 15, 2018, 12:18pm
#10
Estou começando agora com Java.
Não testei, vou testar.
Entendeu o código?
HashMap não é filha de Collection. Por isso quando você tenta fazer o cast para (Collection<Contato>) dá erro.
Sugestão para a sua função…
public Map<Contato,String> getContatos() {
return Collections.unmodifiableMap(this.contatos);
}
Collections.unmodifiableMap é uma função que vai retornar uma referencia para o seu Map mas que não deixará outras classes de fora alterar os valores nela, apenas será possível fazer leitura. Talvez isso seja útil pra vc, da uma olhada.
Mike:
Você fez um cenário que é raro encontrar, esta utilizando a classe Contato como chave para chegar a um valor String, por isso lhe pergunto de novo, o que seria a sua String que esta no map?
Sim, usar <Objeto, String> não é muito normal, da uma revisada nisso.
1 curtida
limassa
Junho 15, 2018, 12:31pm
#12
Então deveria colocar <String,String>?
Mike
Junho 15, 2018, 12:34pm
#13
La vai a pergunta de novo, o que você esta passando como valor do map?
O “certo” seria inverter o cenario, usar <String,Contato>, mas depende do que você quer e da sua ideia
Fazer Map<String,Contato> seria, por exemplo, colocar String = ID do contato e Contato seria o objeto em si com todos os dados.
Seria algo como:
Map<ID, Objeto>
458 - Contato1
741 - Contato2
123 - Contato3
Etc…
Você iria trabalhar com o Map dizendo “mapa, me retorna o objeto da chave 741”, o Map te retorna o objeto Contato2 e ai você faria as coisas necessárias.
mapaContatos.get(“741”);
Porque vc estaria usando o objeto Contato como chave? E o que vc iria retornar nessa String? Qual era seu objetivo?
Entendi, vou fazer um teste, vou alterar o código, e retorno
Se quer retornar todos os contatos dentro de seu Map, faça assim:
public Collection<Contato> getContatos(){
return contatos.values();
}
É importante consultar a documentação para aprender como utilizar as classes:
https://docs.oracle.com/javase/10/docs/api/index.html?java/util/Map.html
2 curtidas
Mike
Junho 15, 2018, 2:13pm
#17
Exato! Ai da até para converter o Map em List caso precise.
List<Contato> contatos = new ArrayList<>(contatos.values());
1 curtida