Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Java Java Data Structures Exploring the Java Collection Framework Maps

Andrew Trachtman
Andrew Trachtman
3,680 Points

A few questions on the challenge

I completed the challenge (SPOILER ALERT: SOLUTION BELOW), but I still feel a bit lost when it comes to using maps and actually tackling these challenges. I'm still a bit confused when it comes to Map.put(); I'm storing the category with the count each time, but it feels redundant to keep putting in a new category key with a new count value each time a new one shows up (Does it even matter since hash insertions and gets are constant time if implemented well?). I understand it in theory, but the usage still confuses me.

Also, if any of you are really good at reading the problems, I'd love tips on that too. It took me awhile to actually understand what the challenge wanted.

I'm also curious to see how everyone else completed the challenge if anyone wanted to post their solutions.

public Map<String, Integer> getCategoryCounts(){
    //Map to return
    Map<String, Integer> map = new HashMap<String, Integer>();
    for(BlogPost blogPost : mPosts){
      //Check if the key exists already, if it does set count to the value of the key.
      Integer categoryCount = map.get(blogPost.getCategory());
      //If we don't have it, we need to set the count to 0 because we will increment every iteration no matter what.
      if(categoryCount == null){
        categoryCount = 0;
      }
      //Add count every iteration
      categoryCount++;
      //Store the results
      map.put(blogPost.getCategory(), categoryCount);
    }
    return map;
  }

1 Answer

Anders Björkland
Anders Björkland
7,481 Points

This is how I solved it:

public Map<String, Integer> getCategoryCounts() {
    Map<String, Integer> categoryCounts = new HashMap<>();
    Integer count;
    for (BlogPost post : mPosts) {
      if (categoryCounts.containsKey(post.getCategory())) {
        count = categoryCounts.get(post.getCategory()) + 1;
        categoryCounts.put(post.getCategory(), count);
      } else {
        categoryCounts.put(post.getCategory(), 1);
      }
    }
    return categoryCounts;
  }  

As you can see, we solved this one a bit different. Now, in regards to "putting in a new category key with a new count value", I'm not sure if I understand you correctly. How I see it, you don't really put in a new key each time, only if the key was not in the map before. Otherwise, the key is simply an index for you to get or put the stored value.

If the stored value was not an immutable object (Integer is), then if you already have a value there that you wish to change in some way, you wouldn't have to do another put. Simply changing the object will change the object in the map (since it is the same object).

The Integer-object is immutable. That means that once it is created, you can't change its value without creating a new object (and thus discarding the previous). If Integer were not immutable, I could have solved the task like this:

public Map<String, Integer> getCategoryCounts() {
    Map<String, Integer> categoryCounts = new HashMap<>();
    Integer count;
    for (BlogPost post : mPosts) {
      if (categoryCounts.containsKey(post.getCategory())) {
        count = categoryCounts.get(post.getCategory());
        count.setValue(count.getValue() + 1); // imagined method to increment the value of a non-immutable Integer-object
      } else {
        categoryCounts.put(post.getCategory(), 1);
      }
    }
    return categoryCounts;
  }  

Now it is easier doing a count++ but this creates a new Integer-object. Which is why we need to put it back in the map where the old object still recides.

Does this makes sense? I may have answered a completely different question you may not even have asked. Oops :P

And, in regards to reading the problems, they can be formulated a bit different from problems formulated in other courses. I also struggle sometimes, so I often resort to see the problem from the perspective of the video I just watched or the previous task I just completed. Sometimes it's just reading the code and figure out what is missing. But, yeah, I see where you are cominig from.

Andrew Trachtman
Andrew Trachtman
3,680 Points

Ok, I think I get what you mean.

"How I see it, you don't really put in a new key each time, only if the key was not in the map before. Otherwise, the key is simply an index for you to get or put the stored value."

What I think you're saying is that since we have this Map object, we're modifying the state of the object. So we're really only adding a key to the map if it wasn't already present. In your example, you check to see if there is already a key for post.getCategory(). If there is, then you take the value that the key returned and add 1 to it. Otherwise you insert a new Key/Value pair with the category as the key and 1 as the value.

Because you're modifying the Map object, it ends up not creating more keys, it just ends up modifying the value that the key was pointing to and then after the loop closes, you return the map object containing our results.

I think I understood that. Either way, it was very helpful. Thank you!