0

How can I override equal and hashcode for the class which has fields describe under?

public class Cartoon {

    private String name;
    private List<CartoonCharacter> characters;

    //other code

    public boolean equals(Object o){
        // ?
    }

    public int hashCode(){
        // ?
    }

}
Primisen
  • 3
  • 2
  • *You* define how / wether or not two objects are equal / have the same hashCode. You could e.g. compare each entry in the list of the objects or ... not. – luk2302 Jul 14 '21 at 10:08
  • 1
    Collections like List or Set implementation along with any other class has equals and hashcode that can be used in you implementation. – Uladzislau Kaminski Jul 14 '21 at 10:09

1 Answers1

0

In equals you have to define what equality really means for your object. In most cases you will have to execute equals on all of the fields, with collections you will need to check their contents if they match.

For the hashcode you can base it on hashcodes of fields you have, you just need to multiply them by different prime numbers and then execute XOR on them (in java represented by ^ symbol). Some more info on this can be found here: Combining Java hashcodes into a "master" hashcode

Here is one of the possible approaches for your case:

public class Cartoon {
    private String name;
    private List<String> characters;

    public boolean equals(Object o){
        if(o instanceof Cartoon){
            Cartoon cartoonToCompare = (Cartoon) o;
            return cartoonToCompare.name.equals(name) && 
                   cartoonToCompare.characters.containsAll(characters));
        }
        return false;
    }

    public int hashCode(){
        return 991 * name.hashCode() ^ 997 * characters.size();
    }

}
Amon
  • 101
  • 5
  • 1
    Since lists can have duplicates and have a defined order, `list1.size() == list2.size() && list1.containsAll(list2)` is not the same as `list1.equals(list2)`, which also implies that `characters.hashCode()` is *not* correct for `haveSameRecords`, as `List`’s hash code has been defined for `equals` semantic. Besides XOR is often used because people are unfamiliar with it, so they think it must be some really advanced thing. In reality, `+` performs better than `^` for most cases. – Holger Jul 27 '21 at 14:00
  • Thanks for the remarks, I have edited my post accordingly. I tend to think that xor is often used because it is better due to the distribution of 1s and 0s in the result. Do you have exact values for the performance difference? – Amon Jul 28 '21 at 10:50
  • 1
    Is there a specific reason why you don’t use `equals` for the lists? I don’t see any requirement in the original question for a different algorithm. Regarding xor vs plus, you can not measure a performance difference in isolation, but it should be obvious that an operator that always evaluates to zero when both operands have the same value, has fundamental flaws when being used for hash codes. The distribution of 1s and 0s in the result is the same for a particular bit position (in fact, the result is the same), but plus produces a carry bit when both are 1, added to the next bit position. – Holger Jul 28 '21 at 11:48