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 - Retired Efficiency! Implement Chooser UI

artistSongs is declared and initialized for every iteration of the for loop. Isn't add() always acting on an empty list?

If a variable is declared and initialized each time a loop iterates, how can we accumulate values or objects in it? Thank you

Can you paste the code here Adiv? Thanks.

I copied this snippet of code manually from a frame in the video lesson

private Map<String, List<Song>> byArtist() {
Map<String, List<Song>> byArtist = new HashMap<>();
for (Song song : mSongs) {
   List<Song> artistSongs = byArtist.get(song.getArtist()); //reinitialized each iteration?
   if (artistSongs == null) {
      artistSongs = new ArrayList<>();
     byArtist.put(song.get(Artist), artistSongs);
    }//if
   artistSongs.add(song); //always adding to empty list? If not how is data preserved each iteration?
}//for

}//byArtist()

Thank you

2 Answers

Dan Johnson
Dan Johnson
40,533 Points

Since you're dealing with a reference to an object, what's basically happening is that artistSongs is being given the same value each time (the reference of the list associated with artist key) so all modifications are done to the same List.

Here's an example that echoes out the changes relative to the map:

public class Application {
    public static void main(String[] args) {
        // HashMap with echo
        ObservedMap example = new ObservedMap();

        // Bands to add to the key "Bands"
        List<String> bands = new ArrayList<>();
        bands.add("Steve Miller Band");
        bands.add("The Rolling Stones");
        bands.add("Queen");

        for(int i = 0; i < bands.size(); i++) {
                        // Get the List reference
            List<String> currentBands = example.get("Bands");
            if(currentBands == null) {
                currentBands = new ArrayList<String>();
                example.put("Bands", currentBands);
            }
            currentBands.add(bands.get(i));
        }
        // Print out the final state:
        example.get("Bands");
    }
}


class ObservedMap extends HashMap<String, List<String>> {
    @Override
    public List<String> get(Object key) {
        List<String> value = super.get(key);

        if(value != null) {
            String report = "Value with key of %s has an element count of %d with the value(s): %s%n";
            System.out.printf(report, key, value.size(), value);
        }
        else {
            System.out.printf("The key %s has no value%n", key);
        }

        return value;
    }
}
Craig Dennis
STAFF
Craig Dennis
Treehouse Teacher

Adiv,

Try to picture the object reference. Maybe this will help. Rewatch Using ArrayLists at the 7:00 minute mark.

Let me know if that helps make it click!

Thank you. I will rewatch that lesson and others. I seem to be getting very confused when dealing with Collection type objects in general (and probably a lot of other concepts, too. LOL). To me, it seems that if a variable is declared in a loop structure, it is reset with each iteration and thus cannot preserve state. I would think that the ArrayList (or whatever data type) should be declared once, outside the loop as that is the only way to preserve its contents between loop iterations.

Also I don't get why we have to write List<String> myList = new ArrayList<>() as opposed to ArrayList<String> myList = new ArrayList<>(), which is how things usually are declared in Java, as far as I can tell).

Scanner scanner = new Scanner(System.in);
Point point = new Point(10,20);
MyClass myclass = new MyClass();

ArrayList implements the List interface. What is gained by declaring an ArrayList object variable with its type specified as the interface (List) instead of the actual data type (ArrayList)? Thank you.