`
iloveflower
  • 浏览: 80739 次
社区版块
存档分类
最新评论
  • iloveflower: 呵呵。好好学习。。。。。。。。。。。。
    java 读书
  • Eric.Yan: 看了一点,不过是电子版的……你这一说到提醒我了,还要继续学习哈 ...
    java 读书

How to override equals method in Java

 
阅读更多
Object class holds some very interesting method which is applicable at object level and one of them is equals () which we are going to discuss in this article. equals () method is used to compare the equality of two object. default implementation of equals() class provided by Object class compares memory location and only return true if two reference variable are pointing to same memory location i.e. essentially they are same object. JAVA recommends to override equals method if equality is going to be define by logical way or via some business logic and some classes in Java standard library does override it e.g. String class whose implementation of equals() method return true if content of two strings are exactly same.
java has provided a contract to follow while overriding equals () method which state that as per Java your equals()  method should adhere following rule:




1) Reflexive: Object must be equal to itself.

2) Symmetric: if a.equals(b) is true then b.equals(a) must be true.

3) Transitive: if a.equals(b) is true and b.equals(c) is true then c.equals(ad) must be true.

4) Consistent: multiple invocation of equals() method must result same value until any of properties are modified. So if two objects are equals in Java they will remain equals until any of there property is modified.

5) Null comparison: comparing any object to null must be false and should not result in NullPointerException. For example a.equals(null) must be false.




And equals method in Java must follow its commitment with hashcode as stated below.




1) If two objects are equal by equals() method then there hashcode must be same.

2) If two objects are unequal by equals() method then there hashcode could be same or different.




So this was the basic theory about equals () method in Java now we are going to discuss the approach on how to override equals () method, yes I know you all know this stuff but I have seen some of equals () code which can really be improved by following correct. For illustration purpose we will see an example of Person class and discuss How to write equals () method for that class.

Overriding equals method in Java

Here is my approach for overriding equals () method in Java. This is based on standard approach most of java programmer follows while writing equals method in Java.




1) Do this check -- if yes then return true.

2) Do null check -- if yes then return false.
3) Do the instanceof check if instanceof return false than return false , after some research I found that instead of instanceof we can use getClass() method for type identification because instanceof check returns true for subclass also, so its not strictly equals comparison until required by business logic. But instanceof check is fine if your class is immutable and no one is going to sub class it. For example we can replace instanceof check by below code
if((obj == null) || (obj.getClass() != this.getClass()))
        return false;




4) Type cast the object; note the sequence instanceof check must be prior to casting object.

5) Compare individual attribute start with numeric attribute because comparing numeric attribute is fast and use short circuit operator for combining checks.  So if first field does not match, don't try to match rest of attribute and return false. It’s also worth to remember doing null check on individual attribute before calling equals() method on them recursively to avoid NullPointerException during equals check in Java.




Code Example of overriding equals method in Java

Let’s see a code example based on my approach of overriding equals method in Java as discussed in above paragraph:
class Person{            private int id;            private String firstName;            private String lastName;                        public int getId() {                        return id;            }                        public void setId(int id) {                        this.id = id;            }                        public String getFirstName() {                        return firstName;            }

        public void setFirstName(String firstName) {                        this.firstName = firstName;            }                        public String getLastName() {                        return lastName;            }                        public void setLastName(String lastName) {                        this.lastName = lastName;            }

        public boolean equals(Object obj){
         if(obj == this){
             return true;
         }
         if(obj == null || obj.getClass() != this.getClass()){
             return false
         }
       
         Person guest = (Person) obj;   
         return id == guest.id &&
                (firstName == guest.firstName || (firstName != null && firstName.equals(guest.getFirstName()) &&
                (lastName  == guest.lastName  ||  (lastName != null && lastName.equals(guest.getLastName());
        }          
If you look above method we are first checking for "this" check which is fastest available check for equals method then we are verifying  whether object is null or not and object is of same type or not. only after verifying type of object we are casting it into desired object to  avoid any ClassCastException in Java. Also while comparing individual attribute we are comparing numeric attribute first ,using short circuit operator to avoid further calculation if its already unequal and doing null check on member attribute to avoid NullPointerException.

           

           

Common Errors while overriding equals in Java

Though equals and hashcode method are defined in Object class and one of fundamental part of Java programming I have seen many programmers making mistake while writing equals() method in Java. I recommend all Java programmer who has just started programming to write couple of equals and hashcode method for there domain or value object to get feel of it. Here I am listing some of common mistakes I have observed on various equals method in Java.



1) Instead of overriding equals() method programmer overloaded it.
This is the most common error I have seen while overriding equals method in Java. Syntax of equals method defined in Object class is public boolean equals(Object obj) but many people unintentionally overload equals method in Java by writing public boolean equals(Person obj), instead of using Object as argument they use there class name. This error is very hard to detect because of static binding. So if you call this method in your class object it will not only compile but also execute correctly but if you try to put your object in collection e.g. ArrayList and call contains() method which is based on equals() method in Java it will not able to detect your object. So beware of it.


2) Second mistake I have seen while overriding equals() method is not doing null check for member variables which ultimately results in NullPointerException during equals() invocation. For example in above code correct way of calling equals() method of member variable is after doing null check as shown below:

firstname == guest.firstname || (firstname != null && firstname.equals(guest.firstname)));


3) Third mistake I have seen is not overriding hashcode method in Java and only overriding equals() method. You must have to override both equals() and hashcode() method in Java , otherwise your value object will not be able to use as key object in HashMap because hashmap in based on equals() and hashcode to read more see , How HashMap works in Java
 
Writing JUnit tests for equals method in Java
Its good practice to write JUnit test cases to test your equals method. Here is my approach for writing JUnit test case for equals method in Java. I will write test cases to check equals behavior on different circumstances:

·          testReflexive() this method will test reflexive nature of equals() method in Java.

·          testSymmeteric() this method will verify symmetric nature of equals() method in Java.

·          testNull() this method will verify null comparison and will pass if equals method returns false.

·          testConsistent() will verify consistent nature of equals method in Java.

·          testNotEquals() will verify if two object which are not supposed to equals is actually not equal

·          testHashcode() will verify that if two objects are equal by equals() method in Java then there hashcode must be same.




5 Tips on Equals method in Java




Tip: most of the IDE provides support to generate equals() and hashcode() method

In Eclipse do the right click-> source -> generate hashCode() and equals().

Tip: if your domain class has any unique business key then just comparing that field in equals method would be enough instead of comparing all the fields e.g. in case of our example if "id" is unique for every person then by just comparing id we will be able to identify whether two persons are equal or not.

Tip: while overriding hashcode method in Java makes sure you use all fields which have been used while writing equals method in Java.

Tip: String and Wrapper classes in java override equals method but StringBuffer doesn’t override it.

Tip: Whenever possible try to make your fields immutable, equals method based on immutable fields are much secure than equals method based on mutable fields.

分享到:
评论

相关推荐

    android @override 报错解决方案

    现象: … java: 1801: method does not override a method from its superclass @Override… 原因: Eclipse is defaulting to Java 1.5 and you have classes implementing interface methods (which in Java 1.6 ...

    The method of type must override a superclass method解决方式, myeclipse, java, web

    在Java编程语言中,"The method of type must override a superclass method" 是一个常见的错误提示,它通常出现在子类试图重写父类方法时,但没有按照正确的格式进行。这个错误通常与多态性和继承概念有关,是理解...

    Java中equals方法隐藏的陷阱

    ### Java中equals方法隐藏的陷阱 在Java编程中,正确实现`equals`方法至关重要,它不仅影响对象的比较逻辑,还直接关系到集合类(如`HashSet`、`HashMap`等)的行为。本文将深入探讨Java中`equals`方法的一些常见...

    Java_重写equals()和hashCode()

    在Java编程语言中,`equals()` 和 `hashCode()` 方法是对象的基本组成部分,它们在很多场景下都发挥着至关重要的作用。这两个方法与对象的相等性比较和哈希表(如HashMap、HashSet)的运作紧密相关。这篇博客将深入...

    Spring Boot in Action

    Spring expert Craig Walls uses interesting and practical examples to teach you both how to use the default settings effectively and how to override and customize Spring Boot for your unique ...

    Android代码-A JUnit rule to easily override Dagger 2 objects

    Using a DaggerMockRule it's possible to override easily (in Java or Kotlin) the objects defined in a Dagger module: Java public class MainServiceTest { @Rule public DaggerMockRule rule = new Dagger

    spring boot in action

    Spring expert Craig Walls uses interesting and practical examples to teach you both how to use the default settings effectively and how to override and customize Spring Boot for your unique ...

    重写equals方法

    在 Java 中,equals 方法是一个非常重要的方法,它用于判断两个对象是否相等,而不是判断两个对象的引用是否相同。在 Object 基类中,equals 方法的实现是使用“==”操作符来比较对象的引用,但是这并不满足实际需求...

    method-override:覆盖HTTP动词

    $ npm install method-override API 注意在需要了解请求方法的任何模块之前使用此模块非常重要(例如,必须在csurf模块之前使用它)。 methodOverride(getter,选项) 创建一个新的中间件函数,以新值覆盖req....

    java7帮助文档

    Documentation is regularly updated to provide developers with in-depth information about new features in the Java platform. Some recent updates include: Swing The JLayer class has been added, which ...

    Java - A Beginner’s Guide - Sixth Edition - Herbert Schildt

    This chapter explains how to define subclasses that inherit from superclasses and how to override methods. It also covers access modifiers and visibility rules, which determine how members of a class...

    覆盖(Override)---马克-to-win Java视频

    覆盖 Override 马克-to-win Java视频的能详细的介绍

    method-override:method-override源码翻译

    $ npm install method-override 原料药 记住这个模块在那些需要知道请求方法的模块之前使用(例如,必须在csurf模块之前使用) methodOverride(getter,options) 创建一个新的中间件函数和设置新的属性值,使用...

    覆盖(Override)2---马克-to-win java视频

    覆盖 Override 马克-to-win java视频的详细描述介绍

    Spring Boot in Action(Manning,2015)

    Spring expert Craig Walls uses interesting and practical examples to teach you both how to use the default settings effectively and how to override and customize Spring Boot for your unique ...

    Java反射之Constructor、Method、Field使用及说明

    在深入探讨Java反射机制中`Constructor`、`Method`、`Field`以及`Class`类的使用之前,我们需要先了解反射的基本概念及其重要性。反射是Java的一项强大功能,它允许程序在运行时检查类和对象的结构,甚至可以创建和...

    java中hashcode()和equals()的详解

    在Java编程语言中,`hashCode()`和`equals()`方法是对象身份验证的关键组成部分,它们主要用于对象的比较和哈希表(如HashMap、HashSet等)的操作。理解这两个方法的工作原理对于编写高效和可靠的代码至关重要。 ...

Global site tag (gtag.js) - Google Analytics