Tras todo lo dicho hasta ahora poco queda que decir. Un mapa, en terminos corrientes es un array asociativo donde tu puedes establecer los pares “clave”, “valor mediante el método mapa.put(clave, valor). Lo único es que recuerdes que guarda objetos, por lo que, aunque lo mas común es que lo uses para guardar cadenas de caracteres, podrias poner cualquier objeto.
Existen dos tipos de mapas, el HashMap y el TreeMap. Aunque en realidad existen mas. El TreeMap es un tipo de mapa ordenado por lo que tiene los siguientes funcionalidades:
Ni que decir tiene que tiene todos los métodos de los contenedores y que hay dos tipos de mapas, el HashMap y el TreeMap. Aqui tienes un ejemplo básico:
// Mapa1.java
// cosas que se pueden hacer con los mañas
import java.util.*;
public class Mapa1{
public static void escribirClaves(Map m){
System.out.println("Tamano = " + m.size()+ ", ");
System.out.println("Claves: = " + m.keySet());
}
public static void escribirValores(Map m){
System.out.println("Tamano = " + m.size()+ ", ");
System.out.println("Valores: = " + m.values());
}
public static Map rellenar(Map m){
// rellenamos el mapa de trabajo....
String[] claves = {"uno","dos","tres","cuatro","cinco"};
String[] valores = {"primer valor", "segundo valor", "tercer valor", "cuarto valor", "quinto valor"};
for(int i=0; i<5;i++){
m.put(claves[i],valores[i]);
}
return m;
}
public static void prueba(Map m){
String clave = "aa", valor = "aa";
rellenar(m);
escribirClaves(m);
escribirValores(m);
System.out.println("El mapa contiene la clave (map.containsKey("+clave+"))?" + m.containsKey(clave));
System.out.println("dame el valor de(map.get("+clave+"))?" + m.get(clave));
System.out.println("El mapa contiene el valor (map.containsValue("+valor+"))?" + m.containsKey(valor));
clave = m.keySet().iterator().next().toString();
System.out.println("La primera clave es:(map.KeySet().iterator().next().toString() )" + m.keySet().iterator().next().toString() );
System.out.println("dame el valor de(map.get("+clave+"))?" + m.get(clave));
System.out.println("Borra "+ clave +" (map.remove("+clave+"))?" + m.remove(clave));
escribirClaves(m);
escribirValores(m);
m.clear();
System.out.println("Borra el mapa ( map.clear() )");
System.out.println("¿Esta vacío? ( map.isEmpty() ) ?" + m.isEmpty());
rellenar(m);
System.out.println("Borra las claves ( map.keySet().removeAll(map.keySet()) )" + m.keySet().removeAll(m.keySet()));
System.out.println("¿Esta vacío? ( map.isEmpty() ) ?" + m.isEmpty());
}
public static void main (String[] args){
System.out.println("Prueba de mapas 1 : HashMap");
prueba( new HashMap() );
System.out.println("Prueba de mapas 2 : TreeMap");
prueba( new TreeMap() );
}
}
Bueno… en un HashMap los OBJETOS se guardan asignándoles un valor de posición que java genera mediante el método hashCode() que tiene todo objeto. Si queremos que el objeto tenga un hashcode concreto pues… ala, a sobreescribir métodos. Igual pasa si queremos buscar instancias en un HashMap. ¿Como se si dos Objetos son iguales?… ¡Haciendo un comparador! Por eso es conveniente reescribir los métodos hashCode() y equals de los objetos llave… Mira estos dos ejemplos y lo entenderas… en el primero, iluso metemos los objetos en un mapa y despues buscamos uno… y nos dice que tururú.
//DetectorPrimavera.java
// ejemplo para ver el hashing.....(los posicionamientos en los mapas)
import java.util.*;
class Meteorologo{
int numeroDeMeteorologo;
Meteorologo(int n){ numeroDeMeteorologo= n; }
public int cual(){ return numeroDeMeteorologo; }
}
class Prediccion{
boolean frio = (Math.random() > 0.4);
public String toString(){ // recuerda que almacenaremos objetos
if(frio){ // y que todo objeto tiene el toString()
return "¡todavia hay frio!"; // por eso tengo que reescribirlo
}else{ // para que diga lo que yo quiera
return "¡Ya ha llegado la primavera!";
}
}
}
public class DetectorPrimavera{
public static void main (String[] args){
HashMap hm = new HashMap();
for(int i=0;i<15;i++){
hm.put(new Meteorologo(i), new Prediccion());
}
System.out.println("hm = " + hm);
System.out.println("buscando al tercero");
Meteorologo mm = new Meteorologo(3);
if(hm.containsKey(mm)){
System.out.println((Prediccion)hm.get(mm)); // si lo encuentras dime que dice
}else{
System.out.println("no hay "+ mm);
}
}
}
Igualmente, es un poco ingenuo ya que se puede intuir que si hacemos un nuevo ejemplar no va a ser exactamente igual que el anterior… bueno.. esto ya entraría en el terreno filosófico y no es mi propósito. observa la salida:
hm = {Meteorologo@1b67f74=¡todavia hay frio!, Meteorologo@10b30a7=¡Ya ha llegado la primavera!, Meteorologo@42e816=¡todavia hay frio!, Meteorologo@9304b1=¡Ya ha llegado la primavera!, Meteorologo@1a758cb=¡Ya ha llegado la primavera!, Meteorologo@173a10f=¡todavia hay frio!, Meteorologo@14318bb=¡Ya ha llegado la primavera!, Meteorologo@190d11=¡todavia hay frio!, Meteorologo@c17164=¡Ya ha llegado la primavera!, Meteorologo@1fb8ee3=¡todavia hay frio!, Meteorologo@de6ced=¡todavia hay frio!, Meteorologo@61de33=¡todavia hay frio!, Meteorologo@ca0b6=¡todavia hay frio!, Meteorologo@a90653=¡Ya ha llegado la primavera!, Meteorologo@69b332=¡todavia hay frio!}
buscando al tercero
no hay Meteorologo@530daa
Como ves, el hashCode es lo que hay detras del @ osea la posicion, el indicador a donde esta. Mira el ejemplo dos… y lo verás todo claro (espero)
//DetectorPrimavera2.java
// ejemplo para ver el hashing.....(los posicionamientos en los mapas)
//
import java.util.*;
class Meteorologo2{
int numeroDeMeteorologo;
Meteorologo2(int n){ numeroDeMeteorologo= n; }
public int cual(){ return numeroDeMeteorologo; } // esto es para saber cual es
public int hashCode(){ return numeroDeMeteorologo; } // hashcode sirve para identificar
public boolean equals(Object o){ // en el mapa.. puedo poner lo mismo.
return (o instanceof Meteorologo2) &&
(numeroDeMeteorologo == ((Meteorologo2)o).numeroDeMeteorologo);
}
}
class Prediccion2{
boolean frio = (Math.random() > 0.3);
public String toString(){ // recuerda que almacenaremos objetos
if(frio){ // y que todo objeto tiene el toString()
return "¡todavia hay frio!"; // por eso tengo que reescribirlo
}else{ // para que diga lo que yo quiera
return "¡Ya ha llegado la primavera!";
}
}
}
public class DetectorPrimavera2{
public static void main (String[] args){
HashMap hm = new HashMap();
for(int i=0;i<15;i++){
hm.put(new Meteorologo2(i), new Prediccion2());
}
System.out.println("hm = " + hm);
System.out.println("buscando al tercero");
Meteorologo2 mm = new Meteorologo2(3);
if(hm.containsKey(mm)){
System.out.println((Prediccion2)hm.get(mm)); // si lo encuentras dime que dice
}else{
System.out.println("no hay "+ mm);
}
}
}
Y ahora en la salida ya tenemos un hashCode mas majo porque hemos reescrito el método que lo produce por otro mucho mas amigable…:
hm = {Meteorologo2@0=¡todavia hay frio!, Meteorologo2@1=¡todavia hay frio!, Meteorologo2@2=¡todavia hay frio!, Meteorologo2@3=¡todavia hay frio!, Meteorologo2@4=¡Ya ha llegado la primavera!, Meteorologo2@5=¡todavia hay frio!, Meteorologo2@6=¡todavia hay frio!, Meteorologo2@7=¡todavia hay frio!, Meteorologo2@8=¡todavia hay frio!, Meteorologo2@9=¡todavia hay frio!, Meteorologo2@a=¡Ya ha llegado la primavera!, Meteorologo2@b=¡todavia hay frio!, Meteorologo2@c=¡todavia hay frio!, Meteorologo2@d=¡todavia hay frio!, Meteorologo2@e=¡todavia hay frio!}
buscando al tercero
¡todavia hay frio!
Por último decirte que si quieres tambien puedes implementar tu propio mapa, con la clase AbstractMap y los métodos Map.Entry y Map.entrySet puedes implementar un mapa como te de la gana a ti. pero eso ya es demasiado para el propósito actual.