0

I am trying to run a getBook() method in a Bookstore program which can allow me to find a book stored in the AL books not only if title and author are correct but also if one of them is null. So, I wrote this code:

public Book getBook(String author, String title){
    boolean condOk = false;
    Book book = null;
    if(books!=null){
        for(int i=0; i<books.size(); i++){
            if((author==null && title.equals(books.get(i).getTitle())) || 
                    (author.equals(books.get(i).getAuthor()) && title==null)){
                condOk = true;
                book = books.get(i);
                break;
            } else if(title.equals(books.get(i).getTitle()) &&
                    author.equals(books.get(i).getAuthor())){
                condOk = true;
                book = books.get(i);
                break;
            }
        }
    }
    if(condOk==false) return null;
    else return book;
}

The J-Unit test (not created by me) of this part, puts in books 4 objects (with constructor: String title, String author, ...) and then it tests the method getBook() three times: with author and title, with title expressed and author null, and a last time with the opposite situation.

I have already tried something and I noticed that if I substitute all the equals() calls with the logical op == everything works fine. In the Book class everything is correct, all the getters and setters are in the right place.

So, why do I get such a behavior, when several times I read that comparing Strings with equals() is better than doing it with ==?

Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
Massimo Baldrighi
  • 365
  • 2
  • 6
  • 17
  • "if I substitute all the equals() calls with the logical op == everything works fine" - it seems more likely that the statement is a wrong conclusion because `equals` *is* the correct method to compare the value of different Strings. For reference types, `a == b` returns true only when a and b are the *same* instance. – user2864740 Sep 13 '14 at 06:32
  • What do you mean by saying "equals is broken"? – Massimo Baldrighi Sep 13 '14 at 06:34
  • @user2864740 Not necessarily. In this case references to the same string constants used. That's why it works fine – ponomandr Sep 13 '14 at 06:34
  • @MassimoBaldrighi I thought it was a custom equals. It is *not* broken over strings so I've removed that language. – user2864740 Sep 13 '14 at 06:34
  • @ponomandr I updated my comment, however the statement at the end about the usage of `==` is *still accurate* and has not changed. (Even interned strings are only `==` *if* both operands are *the same instance*.) – user2864740 Sep 13 '14 at 06:35
  • Check out this post: http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java – ponomandr Sep 13 '14 at 06:36

1 Answers1

0

You run into a NullPointerException, for example if title is null and author is not equal to a book in the list. The condition of the first if is false, so you enter the else part and the condition of the second if cannot be evaluated because in title.equals(books.get(i).getTitle()) the title is null.

This does not happen if you use ==, it is allowed to compare null values with ==.

Henry
  • 42,982
  • 7
  • 68
  • 84
  • But now my question is (and it fits the previous comments too): if my code works with `==` (that is the two objects are the same), doesn't that automatically mean also that the two authors or titles values are the same? In short, why in my case it's not the same if I use `equals()` or `==`? – Massimo Baldrighi Sep 13 '14 at 07:26
  • You get different results because `null == null` is ok, while `null.equals(null)` gives a `NullPointerException`. – Henry Sep 13 '14 at 08:53