EqualsBuilder和HashCodeBuilder

/*
 * Created on Jan 29, 2015
 *
 * Copyright 2006 ATPCO Confidential and Proprietary. All Rights Reserved.
 */
package com.atpco.textload.util;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

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

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

            PoliticalCandidate pc  =  (PoliticalCandidate) o;
            compare  =  ( new  CompareToBuilder( )
                          .append(firstName, pc.firstName)
                          .append(lastName, pc.lastName)).toComparison( );
    }
 
     return  compare;
}

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import bsh.This;

    // get/set方法省略
    public void toString( ) {
        ReflectionToStringBuilder.toString( this );
    }
}

            PoliticalCandidate pc  =  (PoliticalCandidate) o;
            compare  =  ( new  CompareToBuilder( )
                          .append(firstName, pc.firstName)
                          .append(lastName, pc.lastName)).toComparison( );
    }
 
     return  compare;
}

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

// Create a Political Candidate
PoliticalCandidate candidate =
    new PoliticalCandidate( "Jefferson", "Thomas", dob, moneyRaised, va );
    
System.out.println( candidate );

public class Test {

}

 

 public static void main(String[] args) throws Exception {

  MyClass one = new MyClass("Becker", 35);
  MyClass two = new MyClass("Becker", 35);
  MyClass three = new MyClass("Agassi", 33);

  System.out.println("One>>>" + one);
  System.out.println("Two>>>" + two);
  System.out.println("Three>>>" + three);

 

}

 

  System.out.println("one equals two? " + one.equals(two));
  System.out.println("one equals three? " + one.equals(three));

  System.out.println("One HashCode>>> " + one.hashCode());
  System.out.println("Two HashCode>>> " + two.hashCode());
  System.out.println("Three HashCode>>> " + three.hashCode());

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

 }

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);

}

 

}

}

class MyClass {
 private String name = null;
 private int age = 0;

 public MyClass(String name, int age) {
  this.name = name;
  this.age = age;
 }

 public boolean equals(Object obj) {
  return EqualsBuilder.reflectionEquals(this, obj);
 }

 public String toString() {
  return ToStringBuilder.reflectionToString(this,
    ToStringStyle.MULTI_LINE_STYLE);
 }

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

===============================================

 

EqualsBuilder和HashCodeBuilder

 

自动化hashCode()和equals()

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

解决方法:使用EqualsBuilder和HashCodeBuilder

使用举例:

package

com.atpco.textload.util;

 

 

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成员变量。

 

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。

 

 

  CompareToBuilder �C 用于辅助实现Comparable.compareTo(Object)方法;
  
  EqualsBuilder �C 用于辅助实现Object.equals()方法;
  
  HashCodeBuilder �C 用于辅助实现Object.hashCode()方法;
  
  ToStringBuilder �C 用于辅助实现Object.toString()方法;
  
  ReflectionToStringBuilder �C 使用反射机制辅助实现Object.toString()方法;
  
  ToStringStyle �C 辅助ToStringBuilder控制输出格式;
  
  StandardToStringStyle �C 辅助ToStringBuilder控制标准格式。

 

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;

 

该bean里面有个toString()方法,假设有以下操作

 

 

 http://www.blogjava.net/19851985lili/articles/95448.html

 

 // 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]]

 

 

 

 

你可能感兴趣的:(EqualsBuilder,HashCodeBuilder)