3

Effective Java 2e, page 43.

TOPIC : check that the field of the argument matches the corresponding field of this object.

Some object reference fields may legitimately contain null. To avoid the possibility of a NullPointerException, use this idiom to compare such fields:

(field == null ? o.field == null : field.equals(o.field))

This alternative may be faster if field and o.field are often identical:

(field == o.field ||      (field != null && field.equals(o.field)))

Is he implying that field.equals(o.field) produces same behavior as field == o.field ? Can someone explain how the second alternative works ?

Nikhil
  • 797
  • 6
  • 12
  • 30
  • 2
    If they point to the same place they are the same object, the same instance so they are observationality equals.. – nachokk Dec 15 '13 at 21:29
  • 2
    Putting it slightly differently, for any implementation that conforms to the equals contract, if field is not null `field == o.field` implies `field.equals(o.field)` – Patricia Shanahan Dec 15 '13 at 21:47
  • @PatriciaShanahan == tests reference equality while .equals tests value equality so they might not be the same right - http://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java – Nikhil Dec 15 '13 at 22:14
  • @Nik She didn't say they were the same. She said one implies the other. – Dawood ibn Kareem Dec 15 '13 at 22:15

2 Answers2

3

(field == o.field || (field != null && field.equals(o.field)))

If they are both null, this will be true.

If field is null, it will short-circuit to false, safely.

If o.field is null, it will be the field object's responsibility to check for nullness in o.field, which is fine.

If they are identical - i.e. they are the same object, not just equal according to equals() - this will return true and complete quickly.

If they are both not null and not equal, then it will evaluate to false.

Is he implying that field.equals(o.field) produces same behavior as field == o.field ?

No of course not, one of the first things Java programmers learn is not to compare Strings with ==, because they are not the same.

Robin Green
  • 32,079
  • 16
  • 104
  • 187
2
(field == o.field || (field != null && field.equals(o.field)))

Read verbosely translates to

If both are null or they are interned then they are `equal`. 
If they are not equal and field is not null, 
    Then the strings may have equality even if they are not interned. 
    So do a content check for equality of the strings

Basically what he is saying is, that if string1 == string2, then ether they are both null or both are not null, If both are not null and are equal, then the strings must be interned. However if string1 != string2 then one of there things but be true.

  1. field is null or o.field is null
  2. The strings have different content
  3. The strings have the same content and they are not interned

The advantage of doing this is you don't always have to do a comparison for equality by length, then character by character. This can be rather slow if both strings are very, very long.

What is String interning?

Code Example:

public class InternedDemo {

    public static void main(String[] args) {
        String s1 = "hello world";
        String s2 = "hello world";
        String s3 = new String("hello world");

        System.out.println(s1 == s2); // true
        System.out.println(s1 == s3); // false
        System.out.println(s2 == s3); // false

        System.out.println(s1.equals(s3)); // true
        System.out.println(s2.equals(s3)); // true
    }
}
Community
  • 1
  • 1
robbmj
  • 16,085
  • 8
  • 38
  • 63
  • great example thanks. In this text 'field' does not refer to strings alone par se, but any object – Nikhil Dec 15 '13 at 22:11