EqualsBuilder的使用之全等

  • 使用场景
    • 当我们创建一个bean后,往往需要重写它的hashCode方法和equals方法。当bean的属性很多的时候,equals方法的重写将会是个很麻烦的事情。举个栗子:

      public class Status {
      	private String Id;
      
      	private String Name;
      
      	private String Left;
      
      	private String Top;
      
      	private String Width;
      
      	private String Height;
      
      	private String Alt;
      
      	private String Value;
      
      	private String Type;
      
      	private String Tdbh;
      
      	private String Stageid;
      
      	private String Ms;
      
      	private List<Transition> transitions;
      }
      
    这个类当然具备一定的业务含义,现在我们需要重写它的equals方法使得当除transitions属性外的其他属性都相等时返回true,其他情况返回false。在这种使用场景下,我们可以借助equalsBuilder工具类来实现。
  • 使用方法
    • equalsBuilder工具类给我们提供了一系列重载的reflectionEquals方法,有如下几个:

      boolean reflectionEquals(final Object lhs, final Object rhs, final Collection<String> excludeFields)
      
      boolean reflectionEquals(final Object lhs, final Object rhs, final String... excludeFields)
        
      boolean reflectionEquals(final Object lhs, final Object rhs, final boolean testTransients)
        
      boolean reflectionEquals(final Object lhs, final Object rhs, final boolean testTransients, final Class<?> reflectUpToClass,
                  final String... excludeFields)
      
    • 上面三个方法最终都是调用的第四个哈,不信自己看源码咯。说一下参数:
      lhs: 当前对象
      rhs: 对比对象
      testTransients: 用Transients修饰的变量是否参与比较
      reflectUpToClass: 这个一般为null,从来没玩过,不好意思
      excludeFields: 不参与比较的属性名

    • 看一下重点源码哈:

             private static void reflectionAppend(
              final Object lhs,
              final Object rhs,
              final Class<?> clazz,
              final EqualsBuilder builder,
              final boolean useTransients,
              final String[] excludeFields) {
              if (isRegistered(lhs, rhs)) {
                  return;
              }
      
              try {
                  register(lhs, rhs);
                  final Field[] fields = clazz.getDeclaredFields();
                  AccessibleObject.setAccessible(fields, true);
                  for (int i = 0; i < fields.length && builder.isEquals; i++) {
                      final Field f = fields[i];
                      if (!ArrayUtils.contains(excludeFields, f.getName())
                          && (f.getName().indexOf('$') == -1)
                          && (useTransients || !Modifier.isTransient(f.getModifiers()))
                          && (!Modifier.isStatic(f.getModifiers()))) {
                          try {
                              builder.append(f.get(lhs), f.get(rhs));
                          } catch (final IllegalAccessException e) {
                              //this can't happen. Would get a Security exception instead
                              //throw a runtime exception in case the impossible happens.
                              throw new InternalError("Unexpected IllegalAccessException");
                          }
                      }
                  }
              } finally {
                  unregister(lhs, rhs);
              }
          }
      

      通过反射实现的哦!

    • 这个方法在common-lang包中哦,给个maven坐标吧

		<dependency>
           <groupId>commons-lang</groupId>
           <artifactId>commons-lang</artifactId>
           <version>***</version>
           <scope>compile</scope>
        </dependency>
  • 针对上面例子解决方法(随机选的四个方法中的一个,其他的类似)

    private static final List EQUALS_EXCLUDEFIELDS = new ArrayList();
    static{
    EQUALS_EXCLUDEFIELDS.add(“transitions”);
    }

    @Override
    public boolean equals(Object obj) {
    	if (this == obj) {
    		return true;
    	}
    	if (obj == null) {
    		return false;
    	}
    	if (getClass() != obj.getClass()) {
    		return false;
    	}
    	Status other = (Status) obj;
    	return EqualsBuilder.reflectionEquals(this, other,EQUALS_EXCLUDEFIELDS);
    }
    

    要想解放工作量、优化代码,还是要学会用别人的工具类!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值