elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Arreglado, de nuevo, el registro del warzone (wargame) de EHN


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  Java
| | | |-+  Meter un Set en un Map
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: Meter un Set en un Map  (Leído 3,718 veces)
kikian94

Desconectado Desconectado

Mensajes: 66


Ver Perfil
Meter un Set en un Map
« en: 27 Febrero 2015, 14:43 pm »

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:
Código
  1.  
  2. Map<String, Set<Poblacion>> Aprovincias = new HashMap<String, Set<Poblacion>>();
  3.  
  4. public boolean addPoblacion(String provincia, IPoblacion poblacion) {
  5. boolean res = false;
  6. if(!!Aprovincias.containsValue(provincia)){
  7. res = false;
  8. System.out.println("La Provincia no existe, creela antes de añadir poblacion");
  9. }else{
  10.  
  11. //Aprovincias.put(provincia, );
  12.                        Aqui es donde tengo el problema, ya que no se que hacer
  13. }
  14. return res;
  15. }



En línea

Usuario Invitado


Desconectado Desconectado

Mensajes: 625



Ver Perfil
Re: Meter un Set en un Map
« Respuesta #1 en: 27 Febrero 2015, 15:23 pm »

Dado que una Map trabaja con objetos, puedes en primer lugar agregar al mapa solo las provincias e inicializar sus poblaciones con null:

Código
  1. private void fillProvinces(String... provincesNames) {
  2. for(String provinceName : provincesNames)
  3. provinces.add(provinceName, null);
  4. }

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.
Código
  1. public boolean addPopulationToProvince(String provinceName, IPopulation population) {
  2. boolean success = false;
  3. if(!provinces.containsValue(provinceName)) {
  4. System.out.println("La provincia no existe, créela antes de añadir la polación");
  5.                return success;
  6. }
  7. if(provinces.get(provinceName) == null) {
  8. Set<IPopulation> population = new HashSet<>();
  9.        population.add(population);
  10.         provinces.add(provinceName, population);
  11.                success = true;
  12. } else {
  13. Set<IPopulation> population = getPopulationFromProvince(provinceName);
  14. population.add(population);
  15.                success = true;
  16. }
  17.        return success;
  18. }

Éste método devuelve el HashSet población asociado a dicha provincia para poder agregarle elementos:

Código
  1. private Set<IPopulation> getPopulationFromProvince(String provinceName) {
  2. Set<IPopulation> population = null;
  3. for(Map.Entry<String, Set<IPopulation> entry : provinces.entrySet()) {
  4. if(entry.getKey().equals(provinceName))
  5. population = entry.getValue();
  6. }
  7. return population;
  8. }

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 Desconectado

Mensajes: 66


Ver Perfil
Re: Meter un Set en un Map
« Respuesta #2 en: 2 Marzo 2015, 10:09 am »

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 Desconectado

Mensajes: 625



Ver Perfil
Re: Meter un Set en un Map
« Respuesta #3 en: 2 Marzo 2015, 11:40 am »

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 Desconectado

Mensajes: 66


Ver Perfil
Re: Meter un Set en un Map
« Respuesta #4 en: 3 Marzo 2015, 17:49 pm »


vale, creo que ya lo he entendido, he codificado el metodo asi:


Código
  1. public boolean addPoblacion(String provincia, IPoblacion poblacion) {
  2. boolean res = false;
  3. if(!!Aprovincias.containsValue(provincia)){
  4. res = false;
  5. System.out.println("La Provincia no existe, creela antes de añadir poblacion");
  6. }else{
  7. SortedSet<IPoblacion> sPoblacion = (SortedSet<IPoblacion>) getPoblacion(provincia);
  8. sPoblacion.add(poblacion);
  9. Aprovincias.put(provincia, sPoblacion);
  10. res = true;
  11. }
  12. return res;
  13. }


pero al hacer un test del programa con este codigo:

Código
  1. public class test {
  2.  
  3. /**
  4. * @param args
  5. */
  6. public static void main(String[] args) {
  7. // TODO Auto-generated method stub
  8.  
  9. Map<String, Set<IPoblacion>> Aprovincias = new HashMap<String, Set<IPoblacion>>();
  10.  
  11. Poblacion poblacion = new Poblacion("Getafe",0,"Madrid");
  12. Poblacion poblacion2 = new Poblacion("Leganes", 345,"Madrid");
  13.  
  14. AlmacenPoblaciones provincias = new AlmacenPoblaciones();
  15. provincias.addProvincia("Madrid");
  16. provincias.addPoblacion("Madrid", poblacion);
  17. //provincias.addPoblacion("Madrid", poblacion2);
  18. }
  19.  
  20. }

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:
Código
  1. private Set<IPoblacion> getPoblacion(String provincia) {
  2. Set<IPoblacion> poblacion = null;
  3. for(Map.Entry<String, Set<IPoblacion>> entry : Aprovincias.entrySet()) {
  4. if(entry.getKey().equals(provincia))
  5. poblacion = entry.getValue();
  6. }
  7. return poblacion;
  8. }

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 Desconectado

Mensajes: 625



Ver Perfil
Re: Meter un Set en un Map
« Respuesta #5 en: 3 Marzo 2015, 18:58 pm »

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):

Código
  1. package net.elhacker.demo.model.entities;
  2.  
  3. public interface Population {
  4.  
  5. String getProvinceName();
  6.    void setProvinceName(String provinceName);
  7.    int getSomething();
  8.    void setSomething(int value);
  9.    String getStateName();
  10.    void setStateName(String stateName);
  11.  
  12. }

PopulationImp (PoblacionImp):

Código
  1. package net.elhacker.demo.model.entities;
  2.  
  3. public class PopulationImp implements Population {
  4.  
  5. private String provinceName;
  6. private int something;
  7. private String stateName;
  8.  
  9. public PopulationImp() {}
  10.  
  11. public PopulationImp(String provinceName, int something, String stateName) {
  12. super();
  13. this.provinceName = provinceName;
  14. this.something = something;
  15. this.stateName = stateName;
  16. }
  17.  
  18. @Override
  19. public String getProvinceName() {
  20. return provinceName;
  21. }
  22.  
  23. @Override
  24. public void setProvinceName(String provinceName) {
  25. this.provinceName = provinceName;
  26. }
  27.  
  28. @Override
  29. public int getSomething() {
  30. return something;
  31. }
  32.  
  33. @Override
  34. public void setSomething(int something) {
  35. this.something = something;
  36. }
  37.  
  38. @Override
  39. public String getStateName() {
  40. return stateName;
  41. }
  42.  
  43. @Override
  44. public void setStateName(String stateName) {
  45. this.stateName = stateName;
  46. }
  47.  
  48.  
  49. }

PopulationService (Servicio de población). Esto vendría a ser tu "AlmacenPoblaciones":

Código
  1. package net.elhacker.demo.model.services;
  2.  
  3. import java.util.HashMap;
  4. import java.util.HashSet;
  5. import java.util.Map;
  6. import java.util.Set;
  7.  
  8. import net.elhacker.demo.model.entities.Population;
  9.  
  10. public class PopulationService {
  11.  
  12. private static Map<String, Set<Population>> provincesAndPopulations;
  13.  
  14. public PopulationService() {
  15. provincesAndPopulations = new HashMap<>();
  16. }
  17.  
  18. public void addProvince(String provinceName) {
  19. if(provincesAndPopulations.containsKey(provinceName)) return;
  20. provincesAndPopulations.put(provinceName, null);
  21. }
  22.  
  23. public Object[] addPopulation(String provinceName, Population population) {
  24. Object[] response = new Object[2];
  25. if(!provincesAndPopulations.containsKey(provinceName)) {
  26. response[0] = "La provincia no existe, primero créela";
  27. response[1] = false;
  28. } else {
  29. Set<Population> provincePopulation = this.getPopulationByProvinceName(provinceName);
  30. provincePopulation.add(population);
  31. response[0] = "Provincia añadida correctamente";
  32. response[1] = true;
  33. }
  34. return response;
  35. }
  36.  
  37. public boolean addProvinceAndPopulation(String provinceName, Population population) {
  38. boolean success = false;
  39. if(!provincesAndPopulations.containsKey(provinceName)) {
  40. Set<Population> provincePopulation = new HashSet<>();
  41. provincePopulation.add(population);
  42. provincesAndPopulations.put(provinceName, provincePopulation);
  43. success = true;
  44. }
  45. return success;
  46. }
  47.  
  48. private Set<Population> getPopulationByProvinceName(String provinceName) {
  49. Set<Population> population = null;
  50. for(Map.Entry<String, Set<Population>> entry : provincesAndPopulations.entrySet()) {
  51. if(entry.getKey().equals(provinceName))
  52. population = entry.getValue();
  53. }
  54. return population;
  55. }
  56.  
  57. public void showAll() {
  58. for(Map.Entry<String, Set<Population>> entry : provincesAndPopulations.entrySet()) {
  59. System.out.println("Poblaciones del estado "+entry.getKey()+":\n");
  60. for(Population population : entry.getValue()) {
  61. System.out.println(population.getProvinceName());
  62. System.out.println(population.getSomething());
  63. System.out.println(population.getStateName());
  64. System.out.println();
  65. }
  66. System.out.println();
  67. }
  68. }
  69.  
  70.  
  71. }

Test (main):

Código
  1. package net.elhacker.demo;
  2.  
  3. import net.elhacker.demo.model.entities.Population;
  4. import net.elhacker.demo.model.entities.PopulationImp;
  5. import net.elhacker.demo.model.services.PopulationService;
  6.  
  7. public class Test {
  8.  
  9. public static void main(String[] args) {
  10. PopulationService populationService = new PopulationService();
  11. Population population = new PopulationImp("Getafe", 0, "Madrid");
  12. populationService.addProvinceAndPopulation("Madrid", population);
  13. population = new PopulationImp("Leganes", 345, "Madrid");
  14. Object[] response = populationService.addPopulation("Madrid", population);
  15. System.out.println(response[0]);
  16.  
  17. System.out.println("\n*** Mostrando todas las provincias y sus poblaciones ***\n");
  18. populationService.showAll();
  19.  
  20. }
  21.  
  22. }

Resultado de la ejecución:

Citar
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 Desconectado

Mensajes: 66


Ver Perfil
Re: Meter un Set en un Map
« Respuesta #6 en: 4 Marzo 2015, 17:29 pm »

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

Código
  1. public class AlmacenPoblaciones implements IAlmacenPoblaciones {
  2.  
  3. Map<String, SortedSet<IPoblacion>> Aprovincias = new HashMap<String, SortedSet<IPoblacion>>();
  4.  
  5.  
  6. private SortedSet<IPoblacion> getPoblacion(String provincia) {
  7. SortedSet<IPoblacion> poblacion = null;
  8. for(Map.Entry<String, SortedSet<IPoblacion>> entry : Aprovincias.entrySet()) {
  9. if(entry.getKey().equals(provincia))
  10. poblacion = entry.getValue();
  11. }
  12. return poblacion;
  13. }
  14.  
  15. @Override
  16. public boolean addPoblacion(String provincia, IPoblacion poblacion) {
  17. boolean res = false;
  18. if(!Aprovincias.containsKey(provincia)){
  19. res = false;
  20. System.out.println("La Provincia no existe, creela antes de añadir poblacion");
  21. }else{
  22. SortedSet<IPoblacion> sPoblacion = getPoblacion(provincia);
  23. sPoblacion.add(poblacion);                   Aqui es donde me da error y no se por que
  24. Aprovincias.put(provincia, sPoblacion);    Aqui es donde me da error y no se por que
  25. res = true;
  26. }
  27. return res;
  28. }
  29.  
  30.  
  31. @Override
  32. public boolean addProvincia(String provincia) {
  33. SortedSet<IPoblacion> poblaciones = null;
  34. boolean res = false;
  35. if(Aprovincias.containsKey(provincia)){
  36. System.out.println("Ya existe la provincia");
  37. }else{
  38. Aprovincias.put(provincia, poblaciones);
  39. res = true;
  40. }
  41. return res;
  42. }
  43.  
  44. @Override
  45. public boolean containsPoblacion(String provincia, String poblacion) {
  46.  
  47. boolean res = false;
  48. if(!!Aprovincias.containsValue(provincia)){
  49. res = false;
  50. System.out.println("La Provincia no existe, creela antes de eliminar poblacion");
  51. }else{
  52. SortedSet<IPoblacion> sPoblacion = (SortedSet<IPoblacion>) getPoblacion(provincia);
  53. if(sPoblacion.contains(poblacion)){
  54. res = true;
  55. }
  56.  
  57. }
  58. return res;
  59.  
  60. }
  61.  
  62. @Override
  63. public boolean containsPoblacion(String arg0, IPoblacion arg1) {
  64. // TODO Auto-generated method stub
  65. return false;
  66. }
  67.  
  68. @Override
  69. public boolean containsProvincia(String provincia) {
  70. boolean res = false;
  71. if(Aprovincias.containsKey(provincia)){
  72. res = true;
  73. System.out.println("La provincia esta en el almacen");
  74. }else{
  75. System.out.println("La provincia no esta en el almacen");
  76. }
  77. return res;
  78. }


mi metodo main es este

Código
  1. public class test {
  2.  
  3. /**
  4. * @param args
  5. */
  6. public static void main(String[] args) {
  7. // TODO Auto-generated method stu
  8.  
  9. Poblacion poblacion = new Poblacion("Getafe",0,"Madrid");
  10. Poblacion poblacion2 = new Poblacion("Leganes", 345,"Madrid");
  11.  
  12. AlmacenPoblaciones provincias = new AlmacenPoblaciones();
  13. provincias.addProvincia("Madrid");
  14. provincias.addPoblacion("Madrid", poblacion);
  15. provincias.addPoblacion("Madrid", poblacion2);
  16.  
  17. }
  18.  
  19. }
  20.  


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 Desconectado

Mensajes: 625



Ver Perfil
Re: Meter un Set en un Map
« Respuesta #7 en: 4 Marzo 2015, 20:15 pm »

Veo un error aquí:

Código
  1. if(!!Aprovincias.containsValue(provincia)){
  2.    res = false;
  3.  
  4.    System.out.println("La Provincia no existe, creela antes de eliminar poblacion");
  5.  
  6. }

Analiza lo siguiente:

Código
  1. !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:

Código
  1. !!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:

Código
  1. public boolean addProvincia(String provincia) {
  2.  
  3. 34. boolean res = false;
  4.  
  5. 35. if(Aprovincias.containsKey(provincia)){
  6.  
  7. 36. System.out.println("Ya existe la provincia");
  8.  
  9. 37. }else{
  10.  
  11. 38. Aprovincias.put(provincia, null);
  12.  
  13. 39. res = true;
  14.  
  15. 40. }
  16.  
  17. 41. return res;
  18.  
  19. 42. }


¿Devuelve true? Has tests en lugar de adivinar.

Código
  1. boolean response = provincias.addProvincia("Madrid");
  2. System.out.println(response);

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:

Código
  1. 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:

Código
  1. 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 Desconectado

Mensajes: 66


Ver Perfil
Re: Meter un Set en un Map
« Respuesta #8 en: 7 Marzo 2015, 16:59 pm »

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

Código
  1. public boolean guardar(String escritura) {
  2. try{
  3. File fichero = new File (escritura);
  4. FileWriter escribir = new FileWriter (fichero);
  5. for(Map.Entry<String,SortedSet<IPoblacion>> entry: Aprovincias.entrySet()){
  6. escribir.write(entry.getKey() + " " +  entry.getValue());
  7. }
  8. escribir.close();
  9. return true;
  10. }catch(Exception e){
  11. e.printStackTrace();
  12. }
  13. return false;
  14. }
  15.  
  16. @Override
  17. public boolean ordenarPor(String provincia, int ordenarPor) {
  18. // TODO Auto-generated method stub
  19. return false;
  20. }
  21.  
  22. @Override
  23. public boolean recuperar(String arg0) {
  24. // TODO Auto-generated method stub
  25. return false;
  26. }
  27.  
  28.  

al escribir el fichero me dice esto
Código
  1. java.io.FileNotFoundException: c:\prueba.txt (Acceso denegado)
  2. at java.io.FileOutputStream.open(Native Method)
  3. at java.io.FileOutputStream.<init>(Unknown Source)
  4. at java.io.FileOutputStream.<init>(Unknown Source)
  5. at java.io.FileWriter.<init>(Unknown Source)
  6. at AlmacenPoblaciones.guardar(AlmacenPoblaciones.java:276)
  7. at test.main(test.java:26)
  8.  

En línea

kikian94

Desconectado Desconectado

Mensajes: 66


Ver Perfil
Re: Meter un Set en un Map
« Respuesta #9 en: 7 Marzo 2015, 17:09 pm »

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

Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Como meter 5Gb en un DVD?
Multimedia
McHarra 2 1,232 Último mensaje 19 Septiembre 2006, 06:09 am
por .hack//
meter linux en una psp ?
Juegos y Consolas
koopa2 1 934 Último mensaje 27 Octubre 2006, 21:19 pm
por Ragnarok
Meter Juego en 2 CD's
Software
Zinc 1 2,035 Último mensaje 12 Noviembre 2006, 20:35 pm
por peib0l
meter todo en un exe. « 1 2 »
Programación Visual Basic
mig5ueles 10 2,861 Último mensaje 27 Enero 2007, 00:40 am
por ~~
Meter archivos en un .jar
Java
Baal_30 0 990 Último mensaje 16 Marzo 2016, 12:37 pm
por Baal_30
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines