【问题标题】:ArrayList re-using single Object, instead of creating new onesArrayList 重用单个对象,而不是创建新对象
【发布时间】:2017-04-23 04:29:08
【问题描述】:

我正在开发一个简单的程序,它可以读取包含书名和相关参考编号的文本文件。每组信息都应转换为 Book 对象,以便以后对其进行排序。但是,在当前代码中,每当创建新 Book 时,它都会重新使用原始 Book。我在 Book 类中添加了一个计数器来跟踪 Book 对象的数量。

程序应该使用书名和相关的参考编号创建一个新的 Book 对象。 为了解决这个问题,我需要更改/添加什么?

主类

    private static ArrayList<Book> books = new ArrayList();

    public static void main(String[] args) {
        String path = "src//booklist.txt";
        boolean endOfFile = false;

        // try/catch for reading the file
        try {
            FileReader fr = new FileReader(path);
            BufferedReader br = new BufferedReader(fr);

            while (!endOfFile) {
                String line = br.readLine();

                if (line == null) {
                    endOfFile = true;
                } else {
                    books.add(new Book(null, 0));
                    books.get(books.size() - 1).setRefNum(Integer.parseInt(line));

                    String bookTitle = br.readLine();
                    books.get(books.size() - 1).setTitle(bookTitle);
                }
                System.out.println(books.get(books.size() - 1).toString());
            }
            // Closing reader and displaying results
            br.close();
        } catch (IOException e) {
            System.out.println(e.toString());
        }
    }
}

图书课

private String bookTitle;
private int refNum;
private int numBooks;

public Book(String title, int referenceNumber) {
    this.bookTitle = title;
    this.refNum = referenceNumber;
    this.numBooks++;
}

public String getTitle() {
    return this.bookTitle;
}

public void setTitle(String title) {
    this.bookTitle = title;
}

public int getRefNum() {
    return this.refNum;
}

public void setRefNum(int referenceNumber) {
    this.refNum = referenceNumber;
}

public int getNumBooks() {
    return this.numBooks;
}

public String toString() {
    String message = "Book Title: " + this.bookTitle
            + "\nReference #: " + this.refNum
            + "\nBook #: " + this.numBooks
            + "\n";
    return message;
}

文本文档booktitles.txt

1
The Adventures of Tom Sawyer
2
Huckleberry Finn
4
The Sword in the Stone
6
Stuart Little
10
Treasure Island
12
The Secret Garden
14
Alice's Adventures in Wonderland
20
Twenty Thousand Leagues Under the Sea
24
Peter Pan
26
Charlotte's Web
31
A Little Princess
32
Little Women
33
Black Beauty
35
The Merry Adventures of Robin Hood
40
Robinson Crusoe
46
Anne of Green Gables
50
Little House in the Big Woods
52
Swiss Family Robinson
54
The Lion, the Witch and the Wardrobe
56
Heidi
66
A Winkle in Time
100
Mary Poppins

电流输出

Book Title: The Adventures of Tom Sawyer
Reference #: 1
Book #: 1

Book Title: Huckleberry Finn
Reference #: 2
Book #: 1

Book Title: The Sword in the Stone
Reference #: 4
Book #: 1

Book Title: Stuart Little
Reference #: 6
Book #: 1

Book Title: Treasure Island
Reference #: 10
Book #: 1

Book Title: The Secret Garden
Reference #: 12
Book #: 1

Book Title: Alice's Adventures in Wonderland
Reference #: 14
Book #: 1

Book Title: Twenty Thousand Leagues Under the Sea
Reference #: 20
Book #: 1

Book Title: Peter Pan
Reference #: 24
Book #: 1

Book Title: Charlotte's Web
Reference #: 26
Book #: 1

Book Title: A Little Princess
Reference #: 31
Book #: 1

Book Title: Little Women
Reference #: 32
Book #: 1

Book Title: Black Beauty
Reference #: 33
Book #: 1

Book Title: The Merry Adventures of Robin Hood
Reference #: 35
Book #: 1

Book Title: Robinson Crusoe
Reference #: 40
Book #: 1

Book Title: Anne of Green Gables
Reference #: 46
Book #: 1

Book Title: Little House in the Big Woods
Reference #: 50
Book #: 1

Book Title: Swiss Family Robinson
Reference #: 52
Book #: 1

Book Title: The Lion, the Witch and the Wardrobe
Reference #: 54
Book #: 1

Book Title: Heidi
Reference #: 56
Book #: 1

Book Title: A Winkle in Time
Reference #: 66
Book #: 1

Book Title: Mary Poppins
Reference #: 100
Book #: 1

期望的输出

Book Title: The Adventures of Tom Sawyer
Reference #: 1
Book #: 1

Book Title: Huckleberry Finn
Reference #: 2
Book #: 2

Book Title: The Sword in the Stone
Reference #: 4
Book #: 3

Book Title: Stuart Little
Reference #: 6
Book #: 4

Book Title: Treasure Island
Reference #: 10
Book #: 5

Book Title: The Secret Garden
Reference #: 12
Book #: 6

Book Title: Alice's Adventures in Wonderland
Reference #: 14
Book #: 7

Book Title: Twenty Thousand Leagues Under the Sea
Reference #: 20
Book #: 8

Book Title: Peter Pan
Reference #: 24
Book #: 9

Book Title: Charlotte's Web
Reference #: 26
Book #: 10

Book Title: A Little Princess
Reference #: 31
Book #: 11

Book Title: Little Women
Reference #: 32
Book #: 12

Book Title: Black Beauty
Reference #: 33
Book #: 13

Book Title: The Merry Adventures of Robin Hood
Reference #: 35
Book #: 14

Book Title: Robinson Crusoe
Reference #: 40
Book #: 15

Book Title: Anne of Green Gables
Reference #: 46
Book #: 16

Book Title: Little House in the Big Woods
Reference #: 50
Book #: 17

Book Title: Swiss Family Robinson
Reference #: 52
Book #: 18

Book Title: The Lion, the Witch and the Wardrobe
Reference #: 54
Book #: 19

Book Title: Heidi
Reference #: 56
Book #: 20

Book Title: A Winkle in Time
Reference #: 66
Book #: 21

Book Title: Mary Poppins
Reference #: 100
Book #: 22

【问题讨论】:

  • 你有什么问题?
  • 更新帖子,明确提出问题。
  • 你有什么问题?

标签: java arrays oop object arraylist


【解决方案1】:

我认为你误解了代码

books.add(new Book(null, 0));
books.get(books.size() - 1).setRefNum(Integer.parseInt(line));
String bookTitle = br.readLine();
books.get(books.size() - 1).setTitle(bookTitle);

这是每次创建一个新的Book。然而它是低效的。考虑

Book b = new Book(null,0);
books.add(b);
b.setRefNum(Integer.parseInt(line));
String bookTitle = br.readLine();
b.setTitle(bookTitle);

变量b 是循环的本地变量。更好的是,使用构造函数

String bookTitle = br.readLine();
Book b = new Book(bookTitle,Integer.parseInt(line));
books.add(b);

关于已澄清的问题:

numBooks 是一个实例变量,因此每本书都有一个副本。您需要使用books.size() 检索列表中的条目数。从Book 类中删除numBooks,没有必要。

【讨论】:

  • 如果代码只是效率低下,那么他们对重复使用同一本书有什么看法?
  • 这是不清楚的部分。给出的代码没有重用相同的Book 对象。
  • 我想问题是当我输出书籍时,它们都给出了 Book #: 1 的输出。我已经在问题中添加了期望的输出。
【解决方案2】:

在构造函数中使用正确的值,这样就不需要添加 dummy 书,随后也不需要添加 got 来更新

String bookTitle = br.readLine();
books.add(new Book(bookTitle, Integer.parseInt(line)));

【讨论】:

    【解决方案3】:

    添加到 Book 类的计数器不是静态的。所以它对于 Book 对象的每个新实例都是唯一的。所以它永远是一个。

    private int numBooks;
    
    public Book(String title, int referenceNumber) {
        this.bookTitle = title;
        this.refNum = referenceNumber;
        this.numBooks++;
    }
    

    您没有看到从 ArrayList 书籍对象添加的多本书吗?

    System.out.println(books.get(books.size() - 1).toString());
    

    【讨论】:

      【解决方案4】:

      换行

      books.add(new Book(null, 0));
      books.get(books.size() -1).setRefNum(Integer.parseInt(line));
      
      String bookTitle = br.readLine();
      books.get(books.size() - 1).setTitle(bookTitle);
      

      String bookTitle = br.readLine();
      books.add(new Book(bookTitle,Integer.parseInt(line)));
      

      您的问题出在带有 numBooks 的 Book 类中。您不需要这个。您可以使用 arrayList 书籍及其索引进行输出。

      【讨论】:

      • 我已经这样做了,但是,输出仍然将每本书显示为第 1 本书。应该有1本书以上。我已经用当前输出和所需输出更新了问题。
      • 此代码有效。您的问题出在带有 numBooks 的 Book 类中。我想你不需要这个。您可以将 arryList 书籍及其索引用于输出。请参阅我的更新答案。
      【解决方案5】:

      根据您当前的输出,标题正在改变,但书号没有改变。

      numBooks 设为静态。 Static 变量与类链接而不是类的实例,因此相同的变量将在作为同一类的实例的所有对象之间共享。

      【讨论】:

        猜你喜欢
        • 2017-04-12
        • 2013-07-06
        • 2017-02-25
        • 1970-01-01
        • 2012-04-24
        • 1970-01-01
        • 1970-01-01
        • 2012-07-15
        相关资源
        最近更新 更多