在 Java 中动态创建新实例

Dynamically creating a new instance in Java

我有一个名为 CD 的 class,具有以下私有变量:

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

此class用于存储以下格式的输入数据:

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

我有一个 CDParser class 负责逐行解析名为 sample.db 的文件,以将其存储到我们的 CD 对象中。解析后,CD 对象在用 CD newCD = new CD() 初始化后具有以下结构:

artist = "Led Zeppelin"

year = "1979"

albumName = "In Through the Outdoor"

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

现在.. 对于这个项目,sample.db 包含许多相册,如下所示:

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

到目前为止,我已经能够解析所有三个不同的专辑并将它们保存到我的 CD 对象中,但是 运行 进入一个障碍,我只是将所有三个专辑保存到同一个newCD 对象。

我的问题是 - 有没有一种方法可以以编程方式初始化我的 CD 构造函数,它将遵循 newCD1newCD2newCD3 等格式,因为我解析 sample.db?

这意味着,当我解析这个特定文件时:

  1. newCD1 将是专辑 In Through the Outdoor(及其各自的私有变量)

  2. newCD2 将是专辑 II(及其各自的私有变量)

  3. newCD3 将是专辑 Blonde on Blonde,依此类推

这是一种明智的做法吗?或者你能建议我更好的方法吗?

编辑:

附件是我的解析器代码。 ourDB 是一个 ArrayList 包含每一行 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;
        }
    }

问题是您正在使用 CD 的相同对象引用来填充文件解析的值。

每次开始解析新相册的内容时,请确保初始化并存储 CD newCD 的每个实例。

您可以执行以下操作:

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

您当前解析文件的方法有效,但不如应有的可读性。我建议使用两个循环:

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

然后,你的代码

我建议使用Builder设计模式来构建CD对象。如果您总是以相同的顺序读取行,那么实现和使用起来并不复杂。好的教程:http://www.javacodegeeks.com/2013/01/the-builder-pattern-in-practice.html

您只有一个 CD 对象,所以您一直在覆盖它。相反,您可以持有 CD 的集合。例如:

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