EqualsBuilder和HashCodeBuilder

简介: isAssignableFrom()方法是从类继承的角度去判断,instanceof()方法是从实例继承的角度去判断。isAssignableFrom()方法是判断是否为某个类的父类,instanceof()方法是判断是否某个类的子类。

 

isAssignableFrom()方法是从类继承的角度去判断,instanceof()方法是从实例继承的角度去判断。
isAssignableFrom()方法是判断是否为某个类的父类,instanceof()方法是判断是否某个类的子类。

1. Class.isAssignableFrom()方法
Class.isAssignableFrom()是用来判断一个类Class1和另一个类Class2是否相同或是另一个类的子类或接口。
格式为:
Class1.isAssignableFrom(Class2)
调用者和参数都是java.lang.Class类型。

2.Class.instanceof()方法
Class.instanceof()是用来判断一个对象实例是否是一个类或接口的或其子类子接口的实例。
格式是:
obj instanceof TypeName
第一个参数是对象实例名,第二个参数是具体的类名或接口名,例如 String,InputStream。其返回值为boolean。

        System.out.println("String是Object的父类:"+String.class.isAssignableFrom(Object.class));//false
        System.out.println("Object是String的父类:"+Object.class.isAssignableFrom(String.class));//true
        System.out.println("Object和Object相同:"+Object.class.isAssignableFrom(Object.class));//true

        String str = "";
        System.out.println("str是Object的实例:"+str instanceof Object);//true
        Object o = new Object();
        System.out.println("o是Object的实例:"+o instanceof Object);//true

 


package com.osc.demo;

import java.util.List;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

public class Teacher {
    private String name;
    private int age;
    private List<Student> student;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public List<Student> getStudent() {
        return student;
    }

    public void setStudent(List<Student> student) {
        this.student = student;
    }

    @Override
    public boolean equals(Object obj) {
        return EqualsBuilder.reflectionEquals(this, obj);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }
}

 

package com.osc.demo;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

public class Student {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object obj) {
        return EqualsBuilder.reflectionEquals(this, obj);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }
}

 

package com.osc.demo;

import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        Student studentOne = new Student();
        studentOne.setName("张柏芝");
        studentOne.setAge(34);
        List<Student> listOne = new ArrayList<Student>();
        listOne.add(studentOne);
        Teacher teacherOne = new Teacher();
        teacherOne.setName("陈冠希");
        teacherOne.setAge(33);
        teacherOne.setStudent(listOne);

        Student studentTwo = new Student();
        studentTwo.setName("张柏芝");
        studentTwo.setAge(34);
        List<Student> listTwo = new ArrayList<Student>();
        listTwo.add(studentTwo);
        Teacher teacherTwo = new Teacher();
        teacherTwo.setName("陈冠希");
        teacherTwo.setAge(33);
        teacherTwo.setStudent(listTwo);

        System.out.println(teacherOne == teacherTwo);
        System.out.println(teacherOne.equals(teacherTwo));
    }
}

false

true

https://my.oschina.net/moxia/blog/308548

 

自动化hashCode()和equals()
  问题产生:当需要自动实现hashCode()和equals()方法
  解决方法:使用EqualsBuilder和HashCodeBuilder
 
  使用举例:
 

 import  org.apache.commons.lang.builder.HashCodeBuilder;
 import  org.apache.commons.lang.builder.EqualsBuilder;

 public   class  PoliticalCandidate  {
     //  Member variables - omitted for brevity
     //  Constructors - omitted for brevity
     //  get/set methods - omitted for brevity
     //  A hashCode which creates a hash from the two unique identifiers 
 
      public   int  hashCode( )  {
         return   new  HashCodeBuilder( 17 ,  37 )
                       .append(firstName)
                       .append(lastName).toHashCode( );
    } 
 
     //  An equals which compares two unique identifiers 
      public   boolean  equals(Object o)  {
         boolean  equals  =   false ;
         if  ( o  !=   null   && PoliticalCandidate. class .isAssignableFrom(o) )  {
            PoliticalCandidate pc  =  (PoliticalCandidate) o;
            equals  =  ( new  EqualsBuilder( )
                       .append(firstName, ps.firstName)
                       .append(lastName, ps.lastName)).isEquals( );
        } 
         return  equals;
    } 
 
} 

 

Discussion:
1.在上述例子中,当有相同的firstname和lastname时,认为两个对象的hashCode相同,从而equals()返回true.
如果hashCode取决于该class的所有filed时需要使用反射机制来产生一个hashCode。

 public   int  hashCode( )   {
     return  HashCodeBuilder.reflectionHashCode( this 
);
}

和ToStringBuilder 与 HashCodeBuilder一样EqualsBuilder 也是使用append()方法进行配置, EqualsBuilder的append()方法可以接受基本类型、对象、数组作为参数。EqualsBuilder强大的地方在于可以直接把数组作为参数传入append()方法,EqualsBuilder会依次比较数组中的每个元素。
2.如果两个对象相等当且仅当每个属性值都相等 这句话可以由以下代码实现:

 public   boolean  equals(Object o)   {
     return  EqualsBuilder.reflectionEquals( this 
, o);
}

问题提出:需要快速实现compareTo()方法
解决方法:使用CompareToBuilder提供的compareTo()方法。同样的CompareToBuilder也使用了反射机制。以下代码提供了一个compareTo()方法,用于比较两个对象所有的非static和非transient成员变量。

 import  org.apache.commons.lang.builder.CompareToBuilder;

 //  Build a compareTo function from reflection  
 public   int  compareTo(Object o)   {
     return  CompareToBuilder.reflectionCompare( this , obj);

}


Discussion: CompareToBuilder.reflectionCompare()提供了两个对象non-static和nontransient成员变量的方法。 reflectionCompare()方法不予理会static和transient变量,因此以下代码中的averageAge和fullName变量是不会进入比较表达式的。

 public   class  PoliticalCandidate   {
     //  Static variable 

      private   static  String averageAge;

     //  Member variables  

      private  String firstName;
     private 
 String lastName;

     private   transient 
 String fullName;
     // 
 Constructors
     // 
 get/set methods
     //  Build a compareTo function from reflection  

      public   int  compareTo(Object o)  {
         return  CompareToBuilder.reflectionCompare( this 
, obj);
    }
 
 
}

比较对象成员变量的时候应该有一个比较的次序存在,上述代码中默认的应该是先比较lastName,然后是firstName。调用append()方法可以把要比较的变量加入比较表达式中,并且遵循后加入的先比较的次序。
例如:

 public   int  compareTo(Object o)   {
     int  compare  =   - 1 ;  //  By default return less-than 

      if ( o  !=   null   &&  PoliticalCandidate. class .isAssignableFrom( o.getClass( ) ) )  {

            PoliticalCandidate pc  = 
 (PoliticalCandidate) o;
            compare  =  ( new 
 CompareToBuilder( )
                          .append(firstName, pc.firstName)
                          .append(lastName, pc.lastName)).toComparison( );
    }
 
 
    
 return  compare;
}

在比较的时候会先比较lastName,只有在lastName相同的情况下才会比较firstName。
ps:实现compareTo()的时候应保证和equals()规则相同,即当compareTo()返回是0的时候equals()应该返回true。

1.1 ReflectionToStringBuilder

本笔记是在阅读Jakarta Commons Cookbook时所留下的。
1.使用ReflectionToStringBuilder 或者ToStringBuilder 自动产生toString()的内容。
   使用举例:假设有一个表征校长候选人信息的javabean-PoliticalCandidate。
  
public class PoliticalCandidate  {
    private String lastName;
    private String firstName;
    private Date dateOfBirth;
    private BigDecimal moneyRaised;
    private State homeState;

    // get/set方法省略
    public void toString( ) {
        ReflectionToStringBuilder.toString( this );
    }
}

该bean里面有个toString()方法,假设有以下操作:
// Create a State
State va = new State( "VA", "Virginia");

// Create a Birth Date
Calendar calendar = new GregorianCalendar( );
calendar.set( Calendar.YEAR, 1743 );
calendar.set( Calendar.MONTH, Calendar.APRIL );
calendar.set( Calendar.DAY_OF_MONTH, 13 );
Date dob = calendar.getTime( );

BigDecimal moneyRaised = new BigDecimal( 293829292.93 );        

// Create a Political Candidate
PoliticalCandidate candidate = 
    new PoliticalCandidate( "Jefferson", "Thomas", dob, moneyRaised, va );
     
System.out.println( candidate );
假设State对象也是一个使用ReflectionToStringBuilder的javabean,上述程序一种可能的输出为com.discursive.jccook.lang.builders.PoliticalCandidate@187aeca
    [lastName=Jefferson,\firstName=Thomas,
     dateOfBirth=Sat Apr 13 22:38:42 CST 1743,
     moneyRaised=\293829292.930000007152557373046875,
     state=\com.discursive.jccook.lang.builders.State@87816d
         [abbreviation=VA,name=Virginia]]

 

org.apache.commons.lang.builder
  CompareToBuilder – 用于辅助实现Comparable.compareTo(Object)方法;
  
   EqualsBuilder – 用于辅助实现Object.equals()方法;
  
  HashCodeBuilder – 用于辅助实现Object.hashCode()方法;
  
  ToStringBuilder – 用于辅助实现Object.toString()方法;
  
  ReflectionToStringBuilder – 使用反射机制辅助实现Object.toString()方法;
  
  ToStringStyle – 辅助ToStringBuilder控制输出格式;
  
  StandardToStringStyle – 辅助ToStringBuilder控制标准格式。

http://www.blogjava.net/19851985lili/articles/95448.html

 

相关文章
|
SQL Prometheus 监控
数据库连接池选型 Druid vs HikariCP
springboot 现在官方默认的数据库连接池是 HikariCP,HikariCP的性能从测试的数据上来看也是最高的。
数据库连接池选型 Druid vs HikariCP
|
开发工具 git
IDEA中如何使用Git 图文超详细
IDEA中Git使用,实战教程
3379 0
IDEA中如何使用Git 图文超详细
|
SQL 机器学习/深度学习 XML
mybatis-plus分页查询详解
mybatis-plus分页查询详解
7618 0
mybatis-plus分页查询详解
|
11月前
|
Web App开发 机器学习/深度学习 Rust
浅析正则表达式性能问题
浅析正则表达式性能问题
|
存储 Java
java:int强制类型转换成byte
int 在java中是32位, byte是8位 原码:就是二进制码,最高位为符号位,0表示正数,1表示负数,剩余部分表示真值 反码:在原码的基础上,正数反码就是他本身,负数除符号位之外全部按位取反 补码:正数的补码就是自己本身, 负数的补码是在自身反码的基础上加1
java:int强制类型转换成byte
|
Java 编译器 Maven
【Spring技术实战】Spring框架中Aspectj和LoadTimeWeaving的动态代理技术实现指南
【Spring技术实战】Spring框架中Aspectj和LoadTimeWeaving的动态代理技术实现指南
149 0
【Spring技术实战】Spring框架中Aspectj和LoadTimeWeaving的动态代理技术实现指南
|
Java
【Java基础】Java8 使用 stream().filter()过滤List对象(查找符合条件的对象集合)
Java8 使用 stream().filter()过滤List对象(查找符合条件的对象集合)
1050 1
|
JSON 前端开发 Java
Spring Validation参数效验各种使用姿势
在日常的项目开发中,为了防止非法参数对业务造成的影响,需要对接口的参数做合法性校验,例如在创建用户时,需要效验用户的账号名称不能输入中文与特殊字符,手机号、邮箱格式是否准确。
4677 7
|
Java 数据安全/隐私保护
JAVA MD5加密工具类
JAVA MD5加密工具类
372 0
|
XML 缓存 搜索推荐
Git - .gitignore 配置
Git - .gitignore 配置
538 0