设为首页 收藏本站
查看: 776|回复: 0

[经验分享] apache 中的EqualsBuilder和HashCodeBuilder

[复制链接]

尚未签到

发表于 2017-1-2 11:27:08 | 显示全部楼层 |阅读模式
  自动化hashCode()和equals()
  问题产生:当需要自动实现hashCode()和equals()方法
  解决方法:使用EqualsBuilder和HashCodeBuilder 
  使用举例:
 
DSC0000.gif  import  org.apache.commons.lang.builder.HashCodeBuilder;
 import  org.apache.commons.lang.builder.EqualsBuilder;

DSC0001.gif
 public   class  PoliticalCandidate  {
DSC0002.gif     
 //  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 
 

DSC0003.gif       
public   int  hashCode( )  {
        
 return   new  HashCodeBuilder( 17  37 )
                       .append(firstName)
                       .append(lastName).toHashCode( );
DSC0004.gif     } 

 
     
//  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;
    } 

 
DSC0005.gif


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

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-322829-1-1.html 上篇帖子: Apache Commons BeanUtils 简单入门 下篇帖子: apache添加suexec.so模块
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表