-2

The goal of my program is to have the user input 3 books, and if all of the books are different then my code will print all of the books in this format:

Book 1: Title, Author, Publishing year, Cost

Book 2: Title, Author, Publishing year, Cost

Book 3: Title, Author, Publishing year, Cost.

If two of the books are the same, it should print the unique books in this format, with book 1 being the duplicated book:

Book 1: Title, Author, Publishing year, Cost x2

Book 2: Title, Author, Publishing year, Cost

Book 3: Title, Author, Publishing year, Cost

And if three of the books are the same, it should print one book's information with "3x" at the end.

But when I run my code, all three books are printed no matter what and it's as if my if statements didn't even run.

Here is my code for the tester class:

public class BookTester {

    public static void main(String[] args) {

        //Program should be written here:
        System.out.println("Begin Tests");

        Scanner input = new Scanner(System.in);
        int index = 1;
        System.out.println("Enter the title: ");
        String title = input.nextLine();
        System.out.println("Enter the author: ");
        String author = input.nextLine();
        System.out.println("Enter the publishing year: ");
        int year = input.nextInt();
        System.out.println("Enter the cost in double form: ");
        double cost = input.nextDouble();
        Book book1 = new Book(index, title, author, year, cost);

        Scanner input2 = new Scanner(System.in);
        int index2 = 2;
        System.out.println("Enter the title: ");
        String title2 = input2.nextLine();
        System.out.println("Enter the author: ");
        String author2 = input2.nextLine();
        System.out.println("Enter the publishing year: ");
        int year2 = input2.nextInt();
        System.out.println("Enter the cost in double form: ");
        double cost2 = input2.nextDouble();
        Book book2 = new Book(index2, title2, author2, year2, cost2);

        Scanner input3 = new Scanner(System.in);
        int index3 = 3;
        System.out.println("Enter the title: ");
        String title3 = input3.nextLine();
        System.out.println("Enter the author: ");
        String author3 = input3.nextLine();
        System.out.println("Enter the publishing year: ");
        int year3 = input3.nextInt();
        System.out.println("Enter the cost in double form: ");
        double cost3 = input3.nextDouble();
        Book book3 = new Book(index3, title3, author3, year3, cost3);


        if (book1.equals(book2)) {
            System.out.println(book1.toString() + " 2x");
            System.out.println(book3.toString());
        } else if (book1.equals(book3)) {
            System.out.println(book1.toString() + " 2x");
            System.out.println(book2.toString());
        } else if (book2.equals(book3)) {
            System.out.println(book1.toString());
            System.out.println(book2.toString() + " 2x");
        } else if (book1.equals(book2) && book2.equals(book3)) {
            System.out.println(book1.toString() + " 3x");
        } else {
            System.out.println(book1.toString());
            System.out.println(book2.toString());
            System.out.println(book3.toString());
        }
    }
}

And here is my code for my book class:

/**
 * A Book object should be created here
 */
public class Book {
    //Instance Variables
    private int bookIndex;
    private String title;
    private String author;
    private int year;
    private double cost;

    //Constructors
    public Book() {

    }

    public Book(int theIndex, String theTitle, String theAuthor, int theYear, double theCost) {
        bookIndex = theIndex;
        title = theTitle;
        author = theAuthor;
        year = theYear;
        cost = theCost;
    }

    //methods

    public int getIndex() {
        return bookIndex;
    }


    public String getTitle() {
        return title;
    }

    public String getAuthor() {
        return author;
    }

    public int getYear() {
        return year;
    }

    public double getCost() {
        return cost;
    }

    public String toString() {
        return "Book " + getIndex() + ": " + "Title: " + getTitle() + ", " + "Author: " + getAuthor() + ", " + "Publication Year: " + getYear() + ", " + "Cost: " + " $" + getCost();
    }

    public boolean equals(Book other) {
        if (toString() == other.toString()) {
            return true;
        } else {
            return false;
        }
    }
}
zforgo
  • 2,508
  • 2
  • 14
  • 22
  • I think your problem is in the book,equals 'if (toString() == other.toString())' This is still a string compare, use String.equales. – cliff2310 Nov 24 '19 at 23:33

1 Answers1

-1

Basicly the problem is you're using == operator instead of equals() method call. Because you're comparing two Stirngs it means those two Strings has the same memory reference.

Fast fix (Strongly disadvised)

Use toString().equals(other.toString()) instead of == in the equals method. BTW you've just created another equals() method which is used only in one place. You did't override the original equals.

Write good equals method (recommended)

It's a very bad idea to use toString() method to compare two objects are equal or not. It doesn't take long to find two Book objects which gives same toString() but don't equal. Another point is what if the other parameter is null? It will throw a NullPointerException in runtime so will have to investigate what is the problem. Every popular IDE can generate equals() and hashCode() methods. Here is a bulletproof equals() assuming every field is optional

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof Book)) return false;

    Book book = (Book) o;

    if (bookIndex != book.bookIndex) return false;
    if (year != book.year) return false;
    if (Double.compare(book.cost, cost) != 0) return false;
    if (title != null ? !title.equals(book.title) : book.title != null) return false;
    return author != null ? author.equals(book.author) : book.author == null;
}

From Java SE 7 or above you can use Objects.equals()

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof Book)) return false;
    Book book = (Book) o;
    return bookIndex == book.bookIndex &&
            year == book.year &&
            Double.compare(book.cost, cost) == 0 &&
            Objects.equals(title, book.title) &&
            Objects.equals(author, book.author);
}

Conclusion

  1. If Java gives a solution (built-in equals) use it.
  2. If you create your own method it must be bulletproof. Nullchecks and so on.
  3. Never use toString() comparing for object's equality.
zforgo
  • 2,508
  • 2
  • 14
  • 22