Pegar uma chave e um valor especifico de um hashmap [RESOLVIDO]

Olá pessoal,

tenho algo mais ou menos assim

chave valor

carro azul
carro vermelho
carro verde
moto azul
moto vermelho

preciso saber se tenho um par de informação especifica por exemplo (o codigo abaixo não existe, mas era exatamente o que procuro)
hashmap.has(carro,azul) retornaria true
hasmap.has(moto,verde) retorna false

Se não der pra fazer isso com hashmap aceito outras sugestões

Obrigado

Cara, isso não funciona, pelo jeito, você está tentando mapear mais de 1 valor para uma mesma chave. Na prática, para isso que você quer não precisa de Map, basta usar um Set e usar a String como um único valor. Ao invés de (“moto”, “verde”) você usa “moto verde”. Ficaria algo assim:

Set<String> veiculos = new HashSet<String>();

veiculoas.add("carro azul");
veiculoas.add("carro vermelho");
veiculoas.add("carro verde"); 
veiculoas.add("moto azul"); 
veiculoas.add("moto vermelho"); 

boolean b = veiculos.contains("carro azul");

Bom, não sei se é a melhor maneira de fazer, mas funciona:

public static void main(String[] argv) throws Exception 
    {
    	HashMap<String, List<String>> lista1 = new HashMap<String,List<String>>();
    	List<String> resultado;
    	List<String> listaCoresMoto  = new ArrayList<String>();
    	List<String> listaCoresCarro = new ArrayList<String>();
    	
    	listaCoresMoto.add("azul");
    	listaCoresMoto.add("verde");
    	
    	listaCoresCarro.add("preto");
    	listaCoresCarro.add("branco");
    	
    	lista1.put("moto", listaCoresMoto);
    	lista1.put("carro", listaCoresCarro);
    	
    	resultado = (List<String>) lista1.get("moto");
    	
    	if (resultado.contains("XPTO"))
    	{
    		System.out.println("Achou algo aqui");
    	}
    	else
    	{
    		System.out.println("Nada");
    	}
	}

Só de exemplo mesmo.

E porque não um Hashmap, com uma lista de valores para cada key?

Sacanagem o hashmap não ter algo pronto pra verificar se existe o par valor1,valor2

tentei dar um exemplo mais simples do que acontece realmente, mas ainda não consegui ver uma luz no fim do tunel, detalhe, não preciso necessáriamente usar hashmap, só preciso que o algoritmo funcione…

ainda não é o caso real pq senão teria que escrever um livro aqui, mas acho que um exemplo mais próximo da realidade seria assim:

a empresa possui uma lista de produtos e cadastra mais de 100 produtos novos por hora
a empresa possui uma lista de clientes e cadastra uma grande quantidade de clientes por dia

preciso pegar um produto, verificar qual cliente tem a maior compatibilidade com o produto e oferecer pra ele

se ele aceitar, maravilha return true;
se ele recusar, chamo o algoritmo recursivamente, porém o que aconteceria é que o mesmo cliente que recusou seria selecionado novamente pela razão dele ter o maior grau de compatibilidade com aquele produto, por isso preciso ter a informação que o tal cliente recusou o tal produto,

este cliente que recusou o produto não pode mais receber oferta do mesmo produto, mas pode receber oferta de outros

como o sistema está usando varias threads, que estão conversando com action, que conversam com dispositivos mobiles, não consigo usar uma variavel local ou passar parametros, mas uma lista, hashmap ou qualquer outra coisa que seja static resolve, pois todas as classes conseguem ler e alterar as chaves…

mais um exemplo:

cliente 1 - recusou produto 1
cliente 1 - recusou produto 2
cliente 2 - recusou produto 99
cliente 3 - recusou produto 99
cliente infinito - recusou produto infinito

como a quantidade de cliente e produtos é “infinita” não tenho como setar listas no código a não ser que elas fossem criadas em tempo de execução

procuro algo que me retorne true ou false se eu fizer uma busca assim: existeEsseParDeChave(cliente1,produto1)

obrigado

[quote=rmendes08]Cara, isso não funciona, pelo jeito, você está tentando mapear mais de 1 valor para uma mesma chave. Na prática, para isso que você quer não precisa de Map, basta usar um Set e usar a String como um único valor. Ao invés de (“moto”, “verde”) você usa “moto verde”. Ficaria algo assim:

[code]
Set veiculos = new HashSet();

veiculoas.add(“carro azul”);
veiculoas.add(“carro vermelho”);
veiculoas.add(“carro verde”);
veiculoas.add(“moto azul”);
veiculoas.add(“moto vermelho”);

boolean b = veiculos.contains(“carro azul”);
[/code][/quote]

exatamente, uma chave pode ter infinitos valores
a sua explicação me pareceu a mais funcional no meu caso, mas acho que teria que fazer uma gambiarra do tipo

String valor1="carro", valor2="azul";
String resultado = ""+valor1 +valor2;
if(!minhaLista.contains(resultado))
{
//oferece produto para este cliente
}

O que acha ? muita gambiarra ?

Feito directamente aqui, sem testar, mas é para teres uma ideia:

class MyHashmap{

    private Map<String, List<String>> map = new HashMap<String, List<String>>();

    public void put (String key, String object){
        if (map.get(key) == null){
            map.put(key, new ArrayList<String>());
        }
        map.get(key).add(object);
    }

    public void has(String key, String object) {
        if (map.get(key) == null){
            return false;
        }
        return map.get(key).contains(object);
    }
}

[quote=ivolanski][quote=rmendes08]Cara, isso não funciona, pelo jeito, você está tentando mapear mais de 1 valor para uma mesma chave. Na prática, para isso que você quer não precisa de Map, basta usar um Set e usar a String como um único valor. Ao invés de (“moto”, “verde”) você usa “moto verde”. Ficaria algo assim:

[code]
Set veiculos = new HashSet();

veiculoas.add(“carro azul”);
veiculoas.add(“carro vermelho”);
veiculoas.add(“carro verde”);
veiculoas.add(“moto azul”);
veiculoas.add(“moto vermelho”);

boolean b = veiculos.contains(“carro azul”);
[/code][/quote]

exatamente, uma chave pode ter infinitos valores
a sua explicação me pareceu a mais funcional no meu caso, mas acho que teria que fazer uma gambiarra do tipo

String valor1="carro", valor2="azul";
String resultado = ""+valor1 +valor2;
if(!minhaLista.contains(resultado))
{
//oferece produto para este cliente
}

O que acha ? muita gambiarra ?[/quote]

Quase isso, o jeito OO de fazer isso é criar uma classe que represente essa chave. Por exemplo:

class Veiculo{
    private String tipo; //carro, moto, caminhão, etc...
    private String cor; //amarelo, vermelho, etc...

    //getters e setters, equals e hascode (tudo isso o Eclipse pode gerar para você)
}

É bem simples, você cria classe com os 2 atributos e implementa equals e hashCode para essa classe. O Eclipse gera esse código para você, então fica bem fácil. Assim, você pode usar um objeto dessa classe como chave em uma Map ou como valor em um Set.

Caramba, mandou muito bem !!!
parece ser exatamente isso, vou implementar no sistema e ver o que acontece…
fiz umas pequenas alterações, uma delas foi trocar de private para static, assim qualquer outra classe consegue acessar o mesmo hashmap, outra foi um detalhezinho no retorno da função que estava como void

muito obrigado mesmo, parece ser a solução perfeita, elegante e sem gambiarra…

se mais alguem tiver a mesma dúvida vou deixar aqui a classe completa:

package br.com.sistaxi.auxiliar;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PowerHashMap {

 
	  
    static Map<String, List<String>> map = new HashMap<String, List<String>>();  
  
    public void put (String key, String object){  
        if (map.get(key) == null){  
            map.put(key, new ArrayList<String>());  
        }  
        map.get(key).add(object);  
    }  
  
    public boolean has(String key, String object) {  
        if (map.get(key) == null){  
            return false;  
        }  
        return map.get(key).contains(object);  
    }  
}

Muito obrigado a todos, código testado e funcionando perfeitamente !!!

Estou alterando o status para [RESOLVIDO]

Eu deixaria como private mesmo. Se necessário criaria antes um PowerHashMap como static em uma outra classe e utilizaria só os métodos de PowerHashMap

Tal como disse, foi sem testar, directamente aqui no forum :slight_smile:

como faria pra deixar private e todas as classes acessarem os mesmos valores ?

pq se for private e eu fizer

PowerHashMap powerHashMap = new PowerHashMap();

eu terri os metodos mas os valores serão unicos da classe que instanciou, não?

sobre o detalhe do void eu só comentei pq alguem pode vir a ler e tentar usar, etc… mas isso não diminui a maestria do codigo :slight_smile:

vlw

Tens duas hipóteses

  1. Criar uma instancia static de PowerHashMap
class A{

static PowerHashMap map = new PowerHashMap();
...
}


class B{
...
A.map.has(...)
...
}
  1. Aplicar o padrão Singleton
class PowerHashMap{

static PowerHashMap instance = new PowerHashMap();

static PowerHashMap getInstance(){
    return instance;
}

private PowerHashMap(){
//tornar constructor private para garantir que apenas a instância interna é criada
}

private Map<String, List<String>> map = new HashMap<String, List<String>>();    
....