returning the string associated with the year and

2019-09-20 08:05发布

So basically I have a map that looks like this

HashMap<Integer, HashMap<String, Integer>> girls = 
new HashMap<Integer, HashMap<**String**, Integer>>();'

and I want to return the bolded string and this is my method so far

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; 
  }
}

I'm not sure how to do the above title

5条回答
淡お忘
2楼-- · 2019-09-20 08:24

Let's try to see the structure of HashMap<Integer, HashMap<String, Integer>> visually, since it is quite a complex data structure

//             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}
}

Sections A and C are the keys, B and D are the values.

Now let's see what does .get(year).get(rank);. First, get(year) is called. year is a value in section C, so get(year) returns a value in section D. Next, get(rank) is called. Since it is called on the return value of get(year), rank here is a value in section A. get(rank) will return a value in section D, which are all Integers. Therefore, the compiler error occurs.

To fix this, simply swap the two types in the inner map. You change from HashMap<Integer, HashMap<String, Integer>> to HashMap<Integer, HashMap<Integer, String>>.

查看更多
可以哭但决不认输i
3楼-- · 2019-09-20 08:24

As stated, your code will not compile for more than the reason you mentioned.

I think you are misunderstanding how to use a Map. A Map is used like an glossary in a book. A glossary contains a page number for a topic. In a similar sense, a Map contains a value (v [value]) for a given (k [page number]).

But you get to tell the computer what you want to store for what. So, you need to understand your keys and values so that you can construct your map correctly.

查看更多
beautiful°
4楼-- · 2019-09-20 08:30

You can stream the Map doing:

//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);
查看更多
一夜七次
5楼-- · 2019-09-20 08:32

Try

return girls.getOrDefault(year, Collections.emptyMap()).entrySet().stream()
            .filter(e -> e.getValue() == rank)
            .map(e -> e.getKey())
            .findFirst()
            .orElse(null);
查看更多
6楼-- · 2019-09-20 08:49

If you can avoid it, don't use a map of maps. There are reasons and situations where you might want to but it's very confusing, as you've seen yourself.

This is not one of the cases where you want to. Just declare a new class to encapsulate this information and store it in a list:

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;
   }
}

Now your data structure isn't a complete mess:

List<Girl> girls = new ArrayList<>();

and your function is super easy:

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
}
查看更多
登录 后发表回答