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

Bruce Gordon
6,850 PointsUpdating a java map
In the Karaoke machine project there is a method to create a map to keep track of songs by artist. The key is artist and the values are lists of songs for that artist. There is already a complete list of all songs for all artists that was created.
To create the map:
- The map is defined.
- Loop through the full list of songs in the song list one song at a time.
- For each song: a. Read the map by key of artist and get the list of songs so far updated in the map b If the list of songs by artist is null, redefine the list and write it back to the map. c. Add the song to the list
- Return the map
My questions are:
- If when you read the map the list is null, why is it necessary to redefine the list and write it back to the map as an empty list?
- Why isn't the map updated every time through the loop? If you started out with a map with no songs, wouldn't you end up with a map with no songs if you didn't update it?
8 Answers

Jacob Bergdahl
29,119 PointsHi Bruce. Null is not the same as the collection being empty -- it literally means that it doesn't exist! If it's null, you're not redefining it, as it wasn't defined to begin with! I don't see any code so I'm not entirely sure on the implementation of the method you're describing for your second question, however. Please post the code in question and I'm sure we'll figure it out!

Bruce Gordon
6,850 PointsIf you don't update the map every time you get a new song, how could this possibly work? This code is in the Java Data Structures course.
private Map<String, List<Song>> byArtist() { Map<String,List<Song>> byArtist = new HashMap<>(); for (Song song : mSongs) { // read the map to get list of songs by artist that are already in map List<Song> artistSongs = byArtist.get(song.getArtist()); if (artistSongs == null) { artistSongs = new ArrayList<>(); byArtist.put(song.getArtist(), artistSongs); } artistSongs.add(song); } return byArtist; }

Jacob Bergdahl
29,119 PointsAh, you're checking if the artist already has a list of songs. If not, THEN you add it (byArtist.put(params)). Otherwise you just add the song to the list of songs instead.

Bruce Gordon
6,850 PointsIt doesn't make any sense that the only time you do a put is when the list is empty. How are songs being added to the map?

Seth Kroger
56,416 PointsIt's better to think of it as a Map of Lists (of Songs) then a Map of Songs. So you don't add the Songs to the Map directly. You add the List to the Map. Each List is not an independent copy of what you put. It is it's own object you can change by adding, removing, etc, . You then add the Songs to the List. When you want to retrieve the Songs you've added you retrieve the List (of Songs) from the Map and then get the Songs from the List.

Bruce Gordon
6,850 PointsLet's say I start with an empty map that has artist as the key and a list of the artist's songs as the value.
Let's say I have 10 songs by the same artist that I want to add to the map by adding the key of artist and the value of the list.
The first time I read the map there is no list for the artist so I create a new list and I write the list to the map.
Every time I process a song I need to update the list that goes with the artist and need to do a put to the map with that list. So I would have to do at least 10 puts for the map to get all of the songs into the map. If all I do is add a song to a list and not to the map, when the method returns the map, how could it be usable?
Christopher Augg
21,223 PointsBruce,
You said, "It doesn't make any sense that the only time you do a put is when the list is empty. How are songs being added to the map?"
Sorry for the confusion Bruce. Lets see if we can clear this up for you.
1 private Map<String, List<Song>> byArtist() {
2 Map<String, List<Song>> byArtist = new TreeMap<>();
3 for (Song song : mSongs) {
4 List<Song> artistSongs = byArtist.get(song.getArtist());
5 if (artistSongs == null) {
6 artistSongs = new ArrayList<>();
7 byArtist.put(song.getArtist(), artistSongs);
8 }
9 artistSongs.add(song);
10 }
11 return byArtist;
12 }
On line 4 we declare a variable of type List<Song> named artistSongs and assign it to either null or a reference to a list. We do this by calling the byArtist map's get method and passing in a String that we acquire from calling song.getArtist(). You already seem to have a good grasp of how this is done. However, I think where the confusion stems from is the fact that you can get a reference to the list as a value that is within the map. It does not remove the list from the map and the reference is the location of the list in memory.
Therefore, if we get a reference because the list exists, we skip the if block and just add the song to the list. Since artistSongs holds the reference to the list within the map, we can update it directly and not need to use the put method.
I hope this clears it up. Please let us know.
Regards,
Chris

Seth Kroger
56,416 PointsAdding the Song to the List changes the object inside the Map. It may be better to say the Map refers to the List and any changes to the List are reflected when you retrieve the List from the Map, which is the same object you put into the Map and latter manipulated.

Bruce Gordon
6,850 PointsSo if you do a get for a map and and update the value, it automatically updates the map even if you don't do a put? I didn't hear that feature mentioned in the courseware.

Jacob Bergdahl
29,119 PointsIt's not really a feature, it's just how reference types work. A class of an object would work in the exact same way, for instance. As you continue to learn programming, you'll get a better understanding of how variables and reference types work.
Christopher Augg
21,223 PointsBruce,
No, calling the map's get method does not always work this way automatically. It depends on whether or not the object in question is mutable or immutable. I was referring to only the List in this case because the code is making a copy of a List's reference and passing it by value to artistSongs. An instance of a List is mutable; therefore, its contents can be changed through the use of its reference. Conversely, if we had a map with a key-value pair of String & Integer, we could not make a change to the Integer in the same way we did with the List because it is an immutable object. A good read about this topic can be found at javaranch.
Hope this helps.
Regards,
Chris