Search code examples
javalanguage-featurescomparison

Comparing an object with a String using equals() method


In the below example, I am expecting equals() to return true:

public class flower {
    String flower;
    public flower (String flower) {
        this.flower = flower;
    }

    public static void main(String[] args) {
        flower one = new flower("Flower");
        boolean isSame = false;
        if(one.equals("Flower")) {
            isSame = true;
        }
        System.out.print(isSame);
    }
} 

However, the result I get is false... is it because I'm comparing an object with a String? I read the equals() method and is said to compare Strings with Objects. Why am I getting the result as false although they are the same?


Solution

  • The short answer: You need to override the implementation of equals() in your Flower (note: capital F) class. This will do something you like to do:

    @Override
    public boolean equals(Object o) {
        return (o instanceof Flower && ((Flower)o).flower.equals(flower)) ||
                    (o instanceof String && o.equals(flower));
    }
    
    @Override
    public int hashCode() {
        return flower.hashCode();
    }
    

    Overriding hashCode() together with equals() is good form: generally, the 'attributes' (e.g. fields) you pick for doing an equals() should be used in your hashCode() calculation too. In layman terms, they should 'agree' with each other.

    The big/major/severe problem, as pointed out by practically everyone here I presume, is that equals() is meant to be symmetric:

    It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.

    And unfortunately for your Flower class, String.equals(Object) is defined as such:

    The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object. (emphasis mine)

    This means that no String will ever return true when you pass a Flower object to equals().

    Sure, you can still go against the convention, but you'll likely run into bugs - minor or major - very soon when you learn more about the language, e.g. the Collection classes.

    Therefore: avoid such comparisons with equals().