您的位置:首页 > 产品设计 > UI/UE

EqualsBuilder和HashCodeBuilder 作用

2016-05-09 16:04 423 查看
原址:点击打开链接

自动化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控制标准格式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: