java - móviles - manual de programacion android pdf
devolver la cadena asociada con el año y el rango (5)
Así que, básicamente, tengo un mapa que se parece a esto
HashMap<Integer, HashMap<String, Integer>> girls =
new HashMap<Integer, HashMap<**String**, Integer>>();''
y quiero devolver la cadena en negrita y este es mi método hasta ahora
public String getGirlName(int year, int rank) { //year refers to Key
//rank refers to other integer in value map
if (girls.containsKey(year) && girls.get(year).containsKey(rank)){
//shouldn''t this return the name
return girls.get(year).get(rank); //error here where it says I can''t return an integer I have to return a string
else return null;
}
}
No estoy seguro de cómo hacer el título anterior
Como se indicó, su código no se compilará por más de la razón que usted mencionó.
Creo que no entiendes cómo usar un mapa. Un mapa se usa como un glosario en un libro. Un glosario contiene un número de página para un tema. En un sentido similar, un Mapa contiene un valor (v [valor]) para un dado (k [número de página]).
Pero puedes decirle a la computadora qué quieres almacenar para qué. Entonces, necesita comprender sus claves y valores para que pueda construir su mapa correctamente.
Intentemos ver la estructura de HashMap<Integer, HashMap<String, Integer>>
visualmente, ya que es una estructura de datos bastante compleja
// A B
// |--------|--------|
// C D
// |------|---------------------------------------------------------------------|
{
Integer: {String: Integer, String: Integer, String: Integer, String: Integer},
Integer: {String: Integer, String: Integer, String: Integer, String: Integer},
Integer: {String: Integer, String: Integer, String: Integer, String: Integer},
Integer: {String: Integer, String: Integer, String: Integer, String: Integer}
}
Las secciones A y C son las claves, B y D son los valores.
Ahora veamos qué hace .get(year).get(rank);
. Primero, se llama get(year)
. year
es un valor en la sección C, por lo que get(year)
devuelve un valor en la sección D. A continuación, se llama get(rank)
. Dado que se invoca en el valor de retorno de get(year)
, el rank
aquí es un valor en la sección A. get(rank)
devolverá un valor en la sección D, que son todos Integer
. Por lo tanto, se produce el error del compilador.
Para arreglar esto, simplemente intercambie los dos tipos en el mapa interno. Cambia de HashMap<Integer, HashMap<String, Integer>>
a HashMap<Integer, HashMap<Integer, String>>
.
Puede transmitir el mapa haciendo:
//get the map that match the year:
Map<String, Integer> mapForKeyYear = g.getOrDefault(year, null);
//if the map is not null then filter that map to the rank:
String r = mapForKeyYear
.entrySet().stream()
.filter(e -> e.getValue() == rank)
.map(Map.Entry::getKey)
.findFirst().orElse(null);
Si puede evitarlo, no use un mapa de mapas . Hay razones y situaciones en las que quizás quieras, pero es muy confuso, como te has visto a ti mismo.
Este no es uno de los casos en que lo desea. Simplemente declare una nueva clase para encapsular esta información y almacenarla en una lista:
class Girl
{
// Declare getters if you want
public final int year;
public final int rank;
public final String name;
Girl(int year, int rank, String name){
this.year = year;
this.rank = rank;
this.name = name;
}
}
Ahora su estructura de datos no es un desastre completo:
List<Girl> girls = new ArrayList<>();
y tu función es súper fácil:
public String getGirlName(int year, int rank) {
for (Girl girl : girls) {
if (girl.year == year && girl.rank == rank) {
return girl.name;
}
}
throw new RuntimeException("No such girl"); // or whatever
}
Tratar
return girls.getOrDefault(year, Collections.emptyMap()).entrySet().stream()
.filter(e -> e.getValue() == rank)
.map(e -> e.getKey())
.findFirst()
.orElse(null);