0

I am working on a simple program that reads a text file that contains book titles and the associated reference number. Each set of information should be turned into a Book object so that it can be sorted later on. However, in the current code, whenever a new Book should be created, it re-uses the original Book. I have added a counter to the Book class to track the amount of Book objects.

The program should create a new Book object using the book title and associated reference number. What would I change/add in order to fix this problem?

Main Class

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

Book Class

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

Text Document (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

Current Output

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

Desired Output

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
3
  • What is your questions ? Commented Dec 8, 2016 at 2:39
  • Updated post, explicitly asking a question. Commented Dec 8, 2016 at 2:41
  • What is your problem? Commented Dec 8, 2016 at 2:43

5 Answers 5

2

I think you misunderstand the code

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

This is creating a new Book each time. However it is inefficient. Consider

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

Variable b is local to the loop. Even better, use the constructor

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

As to the clarified question:

numBooks is an instance variable so there's one copy for every book. What you need is to use books.size() to retrieve the number of entries in the list. Remove numBooks from the Book class, it is not necessary.

Sign up to request clarification or add additional context in comments.

3 Comments

If the code is merely inefficient, then what are they saying about reusing the same book?
That's part of what is unclear. The code given does not reuse the same Book object.
I guess the issue is that when I output the books, they all give the output of Book #: 1. I've added desired output to the question.
0

use the proper values in the constructor so that a dummy book does not need to be added and subsequently got in order to be updated

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

Comments

0

The counter added to Book class is not static. So it would be unique for each new instance of Book object. So it will always be one.

private int numBooks;

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

Do you not see multiple books added from the ArrayList books object?

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

Comments

0

Replace the lines

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

By

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

Your problem is in the Book class with numBooks.You do not need this . You can use arrayList books and its index for the output.

2 Comments

I have done this, however, the output still shows each book as book #1. There should be more than 1 book. I have updates the question with current output, and desired output.
This code is working . Your problem is in the Book class with numBooks. I think you don not need this . You can use arryList books and its index for the output. See my updated answer.
0

As per your current output, title is changing, but book# is not changing.

Make numBooks static. Static variables are linked with a class instead of being instances of the class, thus the same variable will be shared across all objects which are instance of the same class.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.