EqualsBuilder和HashCodeBuilder

自动化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控制标准格式。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值