Chinaunix首页 | 论坛 | 博客
  • 博客访问: 161232
  • 博文数量: 36
  • 博客积分: 648
  • 博客等级: 上士
  • 技术积分: 335
  • 用 户 组: 普通用户
  • 注册时间: 2011-08-09 15:29
文章分类

全部博文(36)

文章存档

2013年(2)

2012年(26)

2011年(8)

我的朋友

分类: Java

2013-02-05 12:54:26

EqualsBuilderHashCodeBuilder

自动化hashCode()equals()

问题产生:当需要自动实现hashCode()equals()方法

解决方法:使用EqualsBuilderHashCodeBuilder

使用举例:

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.
在上述例子中,当有相同的firstnamelastname,认为两个对象的hashCode相同,从而equals()返回true

如果hashCode取决于该class的所有filed时需要使用反射机制来产生一个hashCode

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

ToStringBuilder  HashCodeBuilder一样EqualsBuilder 也是使用append()方法进行配置, EqualsBuilderappend()方法可以接受基本类型、对象、数组作为参数。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-staticnontransient成员变量的方法。 reflectionCompare()方法不予理会statictransient变量,因此以下代码中的averageAgefullName变量是不会进入比较表达式的。

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

本笔记是在阅读Jakarta Commons Cookbook时所留下的。

1.使用ReflectionToStringBuilder 或者ToStringBuilder 自动产生toString()的内容。

使用举例:假设有一个表征校长候选人信息的javabeanPoliticalCandidate

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对象也是一个使用ReflectionToStringBuilderjavabean,上述程序一种可能的输出为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控制标准格式。

 

阅读(1434) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~