自动化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。
ReflectionToStringBuilder

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控制标准格式。