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控制標準格式。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章