Autor
|
Tema: Meter un Set en un Map (Leído 4,809 veces)
|
kikian94
Desconectado
Mensajes: 66
|
Hola, necesito crear un almacen de provincias, las cuales a su vez tienen poblaciones asociadas, tiene que hacerse con un map en el que la clave es el nombre de la provincia y el valor un set con las poblaciones, hasta ahi todo bien, el problema lo tengo en añadir las poblaciones al set que no se como hacerlo ya que tengo que pasar por el map antes, tengo esta clase: Map<String, Set<Poblacion>> Aprovincias = new HashMap<String, Set<Poblacion>>(); public boolean addPoblacion (String provincia, IPoblacion poblacion ) { boolean res = false; if(!!Aprovincias.containsValue(provincia)){ res = false; System. out. println("La Provincia no existe, creela antes de añadir poblacion"); }else{ //Aprovincias.put(provincia, ); Aqui es donde tengo el problema, ya que no se que hacer } return res; }
|
|
|
En línea
|
|
|
|
Usuario Invitado
Desconectado
Mensajes: 625
|
Dado que una Map trabaja con objetos, puedes en primer lugar agregar al mapa solo las provincias e inicializar sus poblaciones con null: private void fillProvinces (String... provincesNames) { for(String provinceName : provincesNames ) provinces.add(provinceName, null); }
Luego procedemos a agregar las poblaciones a las provincias. Si el Mapa no contiene la provincia, retorna false. Pero si contiene la provincia, realizamos algunos pasos: - Obtener la población asociada a dicha provincia.
Ésto nos permite hacer dos cosas: - Si devuelve null, quiere decir que no hay población para dicha provincia y procedemos a crear un nuevo HashSet, agregamos los valores al HashSet población y lo agregamos al Map.
- Si no devuelve null, quiere decir que ya existe población y entonces, obtenemos la población de la provincia y le agregamos más poblaciones, en lugar de crear otra porque sobre-escribiría el antiguo HashSet.
public boolean addPopulationToProvince (String provinceName, IPopulation population ) { boolean success = false; if(!provinces.containsValue(provinceName)) { System. out. println("La provincia no existe, créela antes de añadir la polación"); return success; } if(provinces.get(provinceName) == null) { Set<IPopulation> population = new HashSet<>(); population.add(population); provinces.add(provinceName, population); success = true; } else { Set<IPopulation> population = getPopulationFromProvince(provinceName); population.add(population); success = true; } return success; }
Éste método devuelve el HashSet población asociado a dicha provincia para poder agregarle elementos: private Set <IPopulation > getPopulationFromProvince (String provinceName ) { Set<IPopulation> population = null; for(Map. Entry<String, Set <IPopulation > entry : provinces. entrySet()) { if(entry.getKey().equals(provinceName)) population = entry.getValue(); } return population; }
Un saludo.
|
|
« Última modificación: 28 Febrero 2015, 15:49 pm por Gus Garsaky »
|
En línea
|
"La vida es muy peligrosa. No por las personas que hacen el mal, si no por las que se sientan a ver lo que pasa." Albert Einstein
|
|
|
kikian94
Desconectado
Mensajes: 66
|
hola, gracias por contestar, la primera parte del codigo la entiendo perfectamente, pero la segunda no, no se utilizar el entrySet para agregar provincias al Set y luego meter el Set en el Map
|
|
|
En línea
|
|
|
|
Usuario Invitado
Desconectado
Mensajes: 625
|
Te explico. Map.Entry simula una entrada de un Map, en este caso del Map provinces. El método entrySet() lo que haces es deolver un set con pares tipo Entry. Entonces, cuál es la entrada del Map provinces? Llave: String, Valor: HashSet, porque de esos valores está compuesto el Map provinces.
Ese método recibe como parámetro el nombre de la provincia. Recorre el mapa entrada por entrada y compara el nombre de la provincia actual que se esta recorriendo con el nombre de la provincia pasada por parámetro. Si coinciden se devuelve el HashSet que contiene laa poblaciones asociadas a dicha provincia.
La logica es sencilla:
1) Obtiene la poblacion de la provincia. 2) Si el HashSet asociado a dicha provincia es Null se crea un HashSet, se le asignan valores y se agrega al Map asociándose con la provincia. 3) Si el HashSet asociado a la provincia no es Null quiere decir que ya hay poblacion para dicha provincia, por lo que se recupera el HashSet y se le agrega otra poblacion.
Espero se haya entendido. Cualquier duda la comentas. Saludos.
|
|
|
En línea
|
"La vida es muy peligrosa. No por las personas que hacen el mal, si no por las que se sientan a ver lo que pasa." Albert Einstein
|
|
|
kikian94
Desconectado
Mensajes: 66
|
vale, creo que ya lo he entendido, he codificado el metodo asi: public boolean addPoblacion (String provincia, IPoblacion poblacion ) { boolean res = false; if(!!Aprovincias.containsValue(provincia)){ res = false; System. out. println("La Provincia no existe, creela antes de añadir poblacion"); }else{ SortedSet<IPoblacion> sPoblacion = (SortedSet<IPoblacion>) getPoblacion(provincia); sPoblacion.add(poblacion); Aprovincias.put(provincia, sPoblacion); res = true; } return res; }
pero al hacer un test del programa con este codigo: public class test { /** * @param args */ public static void main (String[] args ) { // TODO Auto-generated method stub Map<String, Set<IPoblacion>> Aprovincias = new HashMap<String, Set<IPoblacion>>(); Poblacion poblacion = new Poblacion("Getafe",0,"Madrid"); Poblacion poblacion2 = new Poblacion("Leganes", 345,"Madrid"); AlmacenPoblaciones provincias = new AlmacenPoblaciones(); provincias.addProvincia("Madrid"); provincias.addPoblacion("Madrid", poblacion); //provincias.addPoblacion("Madrid", poblacion2); } }
me da nullpointer exception en la linea en la que añado la poblacion al Set, el metodo que utilizo para sacar el set lo he codificado asi: private Set <IPoblacion > getPoblacion (String provincia ) { Set<IPoblacion> poblacion = null; for(Map. Entry<String, Set <IPoblacion >> entry : Aprovincias. entrySet()) { if(entry.getKey().equals(provincia)) poblacion = entry.getValue(); } return poblacion; }
Creo que el error lo tengo en el tipo de objeto que meto en el Set, pero me hago un lio por que el set tiene objetos de tipo Ipoblacion que es una interfaz que tengo que implementar y lo que yo creo son poblaciones de la clase poblacion que es la clase que queda al implementarse Ipoblacion [\quote]
|
|
« Última modificación: 3 Marzo 2015, 17:58 pm por kikian94 »
|
En línea
|
|
|
|
Usuario Invitado
Desconectado
Mensajes: 625
|
Cuando te ocurra una excepción, ponle mucho detalle al rastreo de pila que te muestra. Allí hay mucha información acerca del problema, por eso te lo muestra. Un NullPointerException es una excepción que ocurre cuando se trata de acceder a un valor null. El error que deduzco es que tu el método getPoblacion() no está devolviendo el set. Los errores pueden ser 2: 1) Que no se haya agregado la provincia "Madrid". 2) Que por alguna razón no esté detectando a "Madrid" cuando se itera el mapa. Te he hecho algo parecido para que lo tomes como referencia, por que no sé el contenido de "AlmacenPoblaciones". Population (Población): package net.elhacker.demo.model.entities; public interface Population { void setProvinceName (String provinceName ); int getSomething(); void setSomething(int value); void setStateName (String stateName ); }
PopulationImp (PoblacionImp): package net.elhacker.demo.model.entities; public class PopulationImp implements Population { private int something; public PopulationImp() {} public PopulationImp (String provinceName, int something, String stateName ) { super(); this.provinceName = provinceName; this.something = something; this.stateName = stateName; } @Override public String getProvinceName () { return provinceName; } @Override public void setProvinceName (String provinceName ) { this.provinceName = provinceName; } @Override public int getSomething() { return something; } @Override public void setSomething(int something) { this.something = something; } @Override public String getStateName () { return stateName; } @Override public void setStateName (String stateName ) { this.stateName = stateName; } }
PopulationService (Servicio de población). Esto vendría a ser tu "AlmacenPoblaciones": package net.elhacker.demo.model.services; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import net.elhacker.demo.model.entities.Population; public class PopulationService { private static Map<String, Set<Population>> provincesAndPopulations; public PopulationService() { provincesAndPopulations = new HashMap<>(); } public void addProvince (String provinceName ) { if(provincesAndPopulations.containsKey(provinceName)) return; provincesAndPopulations.put(provinceName, null); } public Object[] addPopulation (String provinceName, Population population ) { if(!provincesAndPopulations.containsKey(provinceName)) { response[0] = "La provincia no existe, primero créela"; response[1] = false; } else { Set<Population> provincePopulation = this.getPopulationByProvinceName(provinceName); provincePopulation.add(population); response[0] = "Provincia añadida correctamente"; response[1] = true; } return response; } public boolean addProvinceAndPopulation (String provinceName, Population population ) { boolean success = false; if(!provincesAndPopulations.containsKey(provinceName)) { Set<Population> provincePopulation = new HashSet<>(); provincePopulation.add(population); provincesAndPopulations.put(provinceName, provincePopulation); success = true; } return success; } private Set <Population > getPopulationByProvinceName (String provinceName ) { Set<Population> population = null; for(Map. Entry<String, Set <Population >> entry : provincesAndPopulations. entrySet()) { if(entry.getKey().equals(provinceName)) population = entry.getValue(); } return population; } public void showAll() { for(Map. Entry<String, Set <Population >> entry : provincesAndPopulations. entrySet()) { System. out. println("Poblaciones del estado "+entry. getKey()+":\n"); for(Population population : entry.getValue()) { System. out. println(population. getProvinceName()); System. out. println(population. getSomething()); System. out. println(population. getStateName()); } } } }
Test (main): package net.elhacker.demo; import net.elhacker.demo.model.entities.Population; import net.elhacker.demo.model.entities.PopulationImp; import net.elhacker.demo.model.services.PopulationService; public class Test { public static void main (String[] args ) { PopulationService populationService = new PopulationService(); Population population = new PopulationImp("Getafe", 0, "Madrid"); populationService.addProvinceAndPopulation("Madrid", population); population = new PopulationImp("Leganes", 345, "Madrid"); Object[] response = populationService. addPopulation("Madrid", population ); System. out. println(response [0]); System. out. println("\n*** Mostrando todas las provincias y sus poblaciones ***\n"); populationService.showAll(); } }
Resultado de la ejecución: Provincia añadida correctamente
*** Mostrando todas las provincias y sus poblaciones ***
Poblaciones del estado Madrid:
Getafe 0 Madrid
Leganes 345 Madrid PD: NO uses doble negación!.
|
|
« Última modificación: 3 Marzo 2015, 19:05 pm por Gus Garsaky »
|
En línea
|
"La vida es muy peligrosa. No por las personas que hacen el mal, si no por las que se sientan a ver lo que pasa." Albert Einstein
|
|
|
kikian94
Desconectado
Mensajes: 66
|
La doble negacion se me ha pasado, lo ejecuto todo pero me dice que no puedo añadir la poblacion por que la provincia no existe, y me da otra vez nullpointerexception public class AlmacenPoblaciones implements IAlmacenPoblaciones { Map<String, SortedSet<IPoblacion>> Aprovincias = new HashMap<String, SortedSet<IPoblacion>>(); private SortedSet <IPoblacion > getPoblacion (String provincia ) { SortedSet<IPoblacion> poblacion = null; for(Map. Entry<String, SortedSet <IPoblacion >> entry : Aprovincias. entrySet()) { if(entry.getKey().equals(provincia)) poblacion = entry.getValue(); } return poblacion; } @Override public boolean addPoblacion (String provincia, IPoblacion poblacion ) { boolean res = false; if(!Aprovincias.containsKey(provincia)){ res = false; System. out. println("La Provincia no existe, creela antes de añadir poblacion"); }else{ SortedSet<IPoblacion> sPoblacion = getPoblacion(provincia); sPoblacion.add(poblacion); Aqui es donde me da error y no se por que Aprovincias.put(provincia, sPoblacion); Aqui es donde me da error y no se por que res = true; } return res; } @Override public boolean addProvincia (String provincia ) { SortedSet<IPoblacion> poblaciones = null; boolean res = false; if(Aprovincias.containsKey(provincia)){ System. out. println("Ya existe la provincia"); }else{ Aprovincias.put(provincia, poblaciones); res = true; } return res; } @Override public boolean containsPoblacion (String provincia, String poblacion ) { boolean res = false; if(!!Aprovincias.containsValue(provincia)){ res = false; System. out. println("La Provincia no existe, creela antes de eliminar poblacion"); }else{ SortedSet<IPoblacion> sPoblacion = (SortedSet<IPoblacion>) getPoblacion(provincia); if(sPoblacion.contains(poblacion)){ res = true; } } return res; } @Override public boolean containsPoblacion (String arg0, IPoblacion arg1 ) { // TODO Auto-generated method stub return false; } @Override public boolean containsProvincia (String provincia ) { boolean res = false; if(Aprovincias.containsKey(provincia)){ res = true; System. out. println("La provincia esta en el almacen"); }else{ System. out. println("La provincia no esta en el almacen"); } return res; }
mi metodo main es este public class test { /** * @param args */ public static void main (String[] args ) { // TODO Auto-generated method stu Poblacion poblacion = new Poblacion("Getafe",0,"Madrid"); Poblacion poblacion2 = new Poblacion("Leganes", 345,"Madrid"); AlmacenPoblaciones provincias = new AlmacenPoblaciones(); provincias.addProvincia("Madrid"); provincias.addPoblacion("Madrid", poblacion); provincias.addPoblacion("Madrid", poblacion2); } }
y la clase poblacion es tal cual tu me la has escrito mas arriba, puede estar el error en el tipo de objeto que añado? ya que la clase es poblacion y el set tiene ipoblacion
|
|
|
En línea
|
|
|
|
Usuario Invitado
Desconectado
Mensajes: 625
|
Veo un error aquí: if(!!Aprovincias.containsValue(provincia)){ res = false; System. out. println("La Provincia no existe, creela antes de eliminar poblacion"); }
Analiza lo siguiente: !Aprovincias.containsValue(provincia)
Si "Madrid" ya está en el Map esto devuelve false. Pero al negar esa condición con nuevamente como estás haciendo: !!Aprovincias.containsValue(provincia)
Ese false se vuelve true y por eso te imprime el mensaje "La provincia no existe".
1) ¿Cuándo añades la provincia solamente: public boolean addProvincia (String provincia ) { 34. boolean res = false; 35. if(Aprovincias.containsKey(provincia)){ 36. System. out. println("Ya existe la provincia"); 37. }else{ 38. Aprovincias.put(provincia, null); 39. res = true; 40. } 41. return res; 42. }
¿Devuelve true? Has tests en lugar de adivinar. boolean response = provincias.addProvincia("Madrid");
Respecto a tu pregunta, la respuesta es NO. Cuando una clase implementa una interface, ésta clase automáticamente se convierte en el mismo tipo de la interfaz. Si tu haces: Población instanceof IPoblacion
Devolverá true, ya que Población al implementar IPoblacion, automáticamente se convierte en tipo de ésta interface. Es por eso que es posible hacer: List<String> lista = new ArrayList<>();
List es una interface y ArrayList es una clase que implementa a List. Recapitulando:- Haz el test anteriormente dicho.
¿Has probado mi clase? No tiene ningún error. Trata de compararlas e identificar errores. En tu próxima respuesta:- Pega el rastreo de pila (El texto rojo que indica el NullPointerException).
Salu2.
|
|
|
En línea
|
"La vida es muy peligrosa. No por las personas que hacen el mal, si no por las que se sientan a ver lo que pasa." Albert Einstein
|
|
|
kikian94
Desconectado
Mensajes: 66
|
ya he solucionado el problema, estaba en que cuando creaba la provincia creaba un set con valor null y yo pensaba que al poner null era que estaba vacio, ahi tenia el error, ahora solo me queda codificar 3 clases mas, una para guardar en fichero, otra para escribir y otra para ordenar por habitantes o nombre public boolean guardar (String escritura ) { try{ for(Map. Entry<String,SortedSet <IPoblacion >> entry : Aprovincias. entrySet()){ escribir.write(entry.getKey() + " " + entry.getValue()); } escribir.close(); return true; e.printStackTrace(); } return false; } @Override public boolean ordenarPor (String provincia, int ordenarPor ) { // TODO Auto-generated method stub return false; } @Override public boolean recuperar (String arg0 ) { // TODO Auto-generated method stub return false; }
al escribir el fichero me dice esto at AlmacenPoblaciones.guardar(AlmacenPoblaciones.java:276) at test.main(test.java:26)
|
|
|
En línea
|
|
|
|
kikian94
Desconectado
Mensajes: 66
|
vale, perdon por la tonteria, el problema era la raiz del disco c, ahora si me deja...., solo me queda el metodo que ordena y el de leer
|
|
« Última modificación: 7 Marzo 2015, 17:13 pm por kikian94 »
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Como meter 5Gb en un DVD?
Multimedia
|
McHarra
|
2
|
1,824
|
19 Septiembre 2006, 06:09 am
por .hack//
|
|
|
meter linux en una psp ?
Juegos y Consolas
|
koopa2
|
1
|
1,486
|
27 Octubre 2006, 21:19 pm
por Ragnarok
|
|
|
Meter Juego en 2 CD's
Software
|
Zinc
|
1
|
2,609
|
12 Noviembre 2006, 20:35 pm
por peib0l
|
|
|
meter todo en un exe.
« 1 2 »
Programación Visual Basic
|
mig5ueles
|
10
|
3,983
|
27 Enero 2007, 00:40 am
por ~~
|
|
|
Meter archivos en un .jar
Java
|
Baal_30
|
0
|
1,418
|
16 Marzo 2016, 12:37 pm
por Baal_30
|
|