theGreenCabbage
theGreenCabbage

Reputation: 4845

Dynamically creating a new instance in Java

I have a class called CD with the following private variables:

private String artist = "";
private String year = "";
private String albumName = "";
private ArrayList<String> songs = new ArrayList<String>();

This class is used to store input data that is in this format:

Led Zeppelin
1979 In Through the Outdoor
-In the Evening
-South Bound Saurez
-Fool in the Rain
-Hot Dog
-Carouselambra
-All My Love
-I'm Gonna Crawl

I have a CDParser class that is in charge of parsing the file called sample.db line by line to store it into our CD object. After parsing, the CD object, after initializing it with CD newCD = new CD() has the following structure:

artist = "Led Zeppelin"

year = "1979"

albumName = "In Through the Outdoor"

songs = {"-In the Evening", "-South Bound Saurez", "-Fool in the Rain", "-Hot Dog"}

Now.. For this project, sample.db contains many albums, which looks like the following:

Led Zeppelin
1979 In Through the Outdoor
-In the Evening
-South Bound Saurez
-Fool in the Rain
-Hot Dog
-Carouselambra
-All My Love
-I'm Gonna Crawl

Led Zeppelin
1969 II
-Whole Lotta Love
-What Is and What Should Never Be
-The Lemon Song
-Thank You
-Heartbreaker
-Living Loving Maid (She's Just a Woman)
-Ramble On
-Moby Dick
-Bring It on Home

Bob Dylan
1966 Blonde on Blonde
-Rainy Day Women #12 & 35
-Pledging My Time
-Visions of Johanna
-One of Us Must Know (Sooner or Later)
-I Want You
-Stuck Inside of Mobile with the Memphis Blues Again
-Leopard-Skin Pill-Box Hat
-Just Like a Woman
-Most Likely You Go Your Way (And I'll Go Mine)
-Temporary Like Achilles
-Absolutely Sweet Marie
-4th Time Around
-Obviously 5 Believers
-Sad Eyed Lady of the Lowlands

I have so far been able to parse all three different albums and save them into my CD object, but ran into a roadblock where I'm simply saving all three albums into the same newCD object.

My question is - is there a way of programmatically initialize my CD constructor that will follow the format newCD1, newCD2, newCD3, etc, as I parse the sample.db?

What this means is, as I parse this particular file:

  1. newCD1 would be the album In Through the Outdoor (and its respective private vars)

  2. newCD2 would be the album II (and its respective private vars)

  3. newCD3 would be the album Blonde on Blonde, and so on

Is this a smart way to do it? Or could you suggest me a better way?

EDIT:

Attached is my parser code. ourDB is an ArrayList containing every line of sample.db:

    CD newCD = new CD();

    int line = 0;

    for(String string : this.ourDB) {
        if(line == ARTIST) {
            newCD.setArtist(string);
            System.out.println(string);
            line++;
        } else if(line == YEAR_AND_ALBUM_NAME){
            String[] elements = string.split(" ");

            String[] albumNameArr = Arrays.copyOfRange(elements, 1, elements.length);

            String year = elements[0];
            String albumName = join(albumNameArr, " ");

            newCD.setYear(year);
            newCD.setAlbumName(albumName);

            System.out.println(year);
            System.out.println(albumName);

            line++;
        } else if(line >= SONGS && !string.equals("")) {
            newCD.setSong(string);
            System.out.println(string);
            line++;
        } else if(string.isEmpty()){
            line = 0;
        }
    }

Upvotes: 3

Views: 169

Answers (3)

Mureinik
Mureinik

Reputation: 311308

You have a single CD object, so you keep overwriting it. Instead, You could hold a collection of CDs. E.g.:

List<CD> cds = new ArrayList<>();

CD newCD = new CD();
int line = 0;

for(String string : this.ourDB) {
    if(line == ARTIST) {
        newCD.setArtist(string);
        System.out.println(string);
        line++;
    } else if(line == YEAR_AND_ALBUM_NAME){
        String[] elements = string.split(" ");

        String[] albumNameArr = Arrays.copyOfRange(elements, 1, elements.length);

        String year = elements[0];
        String albumName = join(albumNameArr, " ");

        newCD.setYear(year);
        newCD.setAlbumName(albumName);

        System.out.println(year);
        System.out.println(albumName);

        line++;
    } else if(line >= SONGS && !string.equals("")) {
        newCD.setSong(string);
        System.out.println(string);
        line++;
    } else if(string.isEmpty()){
        // We're starting a new CD!
        // Add the one we have so far to the list, and start afresh
        cds.add(newCD);
        newCD = new CD();
        line = 0;
    }
}

// Take care of the case the file doesn't end with a newline:
if (line != 0) {
    cds.add(newCD);
}

Upvotes: 7

Luiggi Mendoza
Luiggi Mendoza

Reputation: 85779

The problem is that you're using the same object reference of CD to fill the values of the parse of the file.

Just make sure to initialize and store every instance of CD newCD every time you start parsing the content of a new album.

You may do the following:

List<CD> cdList = new ArrayList<>();
for (<some way to handle you're reading a new album entry from your file>) {
    CD cd = new CD();
    //method below parses the data in the db per album entry
    //an album entry may contain several lines
    parseData(cd, this.ourDB);
    cdList.add(cd);
}
System.out.println(cdList);

Your current way to parse the file works but is not as readable as it should be. I would recommend using two loops:

List<CD> cdList = new ArrayList<>();
Iterator<String> yourDBIterator = this.ourDB.iterator();
//it will force to enter the first time
while (yourDBIterator.hasNext()) {
    //do the parsing here...
    CD cd = new CD();
    //method below parses the data in the db per album entry
    //an album entry may contain several lines
    parseData(cd, yourDBIterator);
    cdList.add(cd);
}

//...
public void parseData(CD cd, Iterator<String> it) {
    String string = it.next();
    int line = ARTIST;
    while (!"".equals(string)) {
        if (line == ARTIST) {
            newCD.setArtist(string);
            System.out.println(string);
            line++;
        } else if(line == YEAR_AND_ALBUM_NAME){
            String[] elements = string.split(" ");
            String[] albumNameArr = Arrays.copyOfRange(elements, 1, elements.length);
            String year = elements[0];
            String albumName = join(albumNameArr, " ");
            newCD.setYear(year);
            newCD.setAlbumName(albumName);
            System.out.println(year);
            System.out.println(albumName);
            line++;
        } else if(line >= SONGS && !string.equals("")) {
            newCD.setSong(string);
            System.out.println(string);
            line++;
        }
        if (it.hasNext()) {
            string = it.next();
        } else {
            string = "";
        }
    }
}

Then, your code

Upvotes: 5

Thomas Weglinski
Thomas Weglinski

Reputation: 1094

I suggest to use the Builder design pattern to construct the CD object. If you read lines always in the same order, it will be not complicated to implement and use. Good tutorial: http://www.javacodegeeks.com/2013/01/the-builder-pattern-in-practice.html

Upvotes: 0

Related Questions