zoukankan      html  css  js  c++  java
  • EqualsBuilder和HashCodeBuilder

    isAssignableFrom()方法是从类继承的角度去判断,instanceof()方法是从实例继承的角度去判断。
    isAssignableFrom()方法是判断是否为某个类的父类,instanceof()方法是判断是否某个类的子类。

    1. Class.isAssignableFrom()方法
    Class.isAssignableFrom()是用来判断一个类Class1和另一个类Class2是否相同或是另一个类的子类或接口。
    格式为:
    Class1.isAssignableFrom(Class2)
    调用者和参数都是java.lang.Class类型。

    2.Class.instanceof()方法
    Class.instanceof()是用来判断一个对象实例是否是一个类或接口的或其子类子接口的实例。
    格式是:
    obj instanceof TypeName
    第一个参数是对象实例名,第二个参数是具体的类名或接口名,例如 String,InputStream。其返回值为boolean。

            System.out.println("String是Object的父类:"+String.class.isAssignableFrom(Object.class));//false
            System.out.println("Object是String的父类:"+Object.class.isAssignableFrom(String.class));//true
            System.out.println("Object和Object相同:"+Object.class.isAssignableFrom(Object.class));//true
    
            String str = "";
            System.out.println("str是Object的实例:"+str instanceof Object);//true
            Object o = new Object();
            System.out.println("o是Object的实例:"+o instanceof Object);//true


    package com.osc.demo;
    
    import java.util.List;
    
    import org.apache.commons.lang.builder.EqualsBuilder;
    import org.apache.commons.lang.builder.HashCodeBuilder;
    
    public class Teacher {
        private String name;
        private int age;
        private List<Student> student;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public List<Student> getStudent() {
            return student;
        }
    
        public void setStudent(List<Student> student) {
            this.student = student;
        }
    
        @Override
        public boolean equals(Object obj) {
            return EqualsBuilder.reflectionEquals(this, obj);
        }
    
        @Override
        public int hashCode() {
            return HashCodeBuilder.reflectionHashCode(this);
        }
    }
    package com.osc.demo;
    
    import org.apache.commons.lang.builder.EqualsBuilder;
    import org.apache.commons.lang.builder.HashCodeBuilder;
    
    public class Student {
        private String name;
        private int age;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public boolean equals(Object obj) {
            return EqualsBuilder.reflectionEquals(this, obj);
        }
    
        @Override
        public int hashCode() {
            return HashCodeBuilder.reflectionHashCode(this);
        }
    }
    package com.osc.demo;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Test {
        public static void main(String[] args) {
            Student studentOne = new Student();
            studentOne.setName("张柏芝");
            studentOne.setAge(34);
            List<Student> listOne = new ArrayList<Student>();
            listOne.add(studentOne);
            Teacher teacherOne = new Teacher();
            teacherOne.setName("陈冠希");
            teacherOne.setAge(33);
            teacherOne.setStudent(listOne);
    
            Student studentTwo = new Student();
            studentTwo.setName("张柏芝");
            studentTwo.setAge(34);
            List<Student> listTwo = new ArrayList<Student>();
            listTwo.add(studentTwo);
            Teacher teacherTwo = new Teacher();
            teacherTwo.setName("陈冠希");
            teacherTwo.setAge(33);
            teacherTwo.setStudent(listTwo);
    
            System.out.println(teacherOne == teacherTwo);
            System.out.println(teacherOne.equals(teacherTwo));
        }
    }

    false

    true

    https://my.oschina.net/moxia/blog/308548

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

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

  • 相关阅读:
    JDK源代码学习-基础类
    六、Java多人博客系统-2.0版本-代码实现
    JDK源代码学习-ArrayList、LinkedList、HashMap
    Java拓展接口-default关键词
    七、Java多人博客系统-2.0版本-docker部署
    五、Java多人博客系统-2.0版本-数据库设计
    四、Java多人博客系统-2.0版本
    max file descriptors [10240] for elasticsearch process is too low, increase to at least [65535]
    system call filters failed to install; check the logs and fix your configuration or disable system call filters at your own risk
    which: no java in (/sbin:/usr/sbin:/bin:/usr/bin) Could not find any executable java binary. Please install java in your PATH or set JAVA_HOME
  • 原文地址:https://www.cnblogs.com/softidea/p/5952419.html
Copyright © 2011-2022 走看看