zoukankan      html  css  js  c++  java
  • Guava源码分析——Objects

    Objects工具类,可以分为两部分来分析。一部分是equals()和hashcode()方法的支持。另一部分是toString()和compareTo()的链式调用的支持。

    对于equals()方法,Guava的Objects类提供了如下支持:

    public static boolean equal(@Nullable Object a, @Nullable Object b){
        return a == b || (a != null && a.equals(b));
    }

    对于hashcode()方法,Guava的Objects类提供了如下支持:

    public static int hashCode(@Nullable Object... objects) {
        return Arrays.hashCode(objects);
    }

    equal()方法的实现,比较简单,采用Objects.equal(a,b),很巧妙的避免了a.equals(b)时,NullPointerException的出现。

    hashcode()方法的实现,也是比较简单。

    一般情况下,重写hashcode()和equals()方法的时候都会使用IDE直接生成,如下所示:

    public class Person {
        private int id;
        private String name;
        private int age;
    
        @Override
        public int hashCode() {
            int result = id;
            result = 31 * result + (name != null ? name.hashCode() : 0);
            result = 31 * result + age;
            return result;
        }
    }

    可以看出重写后的方法会让使用者很困惑,究竟哪些字段参与了比较。而Objects中的hashcode()方法可以很好的解决这个问题。如下代码所示:

    public class Person {
        private int id;
        private String name;
        private int age;
    
        @Override
        public int hashCode() {
            return Objects.hashCode(id, name, age);
        }
    }

    需要注意的是。在Java7后,Guava让我们使用java.util.Objects,替代Guava的Objects,API参数是一样的。

    Objects另一个需要阐述的地方,是对toString()和compare()方法的支持。

    对于toString()方法的链式调用的支持。如下代码所示:

    public class Person {
        private int id;
        private String name;
        private int age;
    
        @Override
        public String toString() {
            return MoreObjects.toStringHelper(this).add("id", id).add("name", name).add("age", age).toString();
        }
    }

    下面,我们分析一下MoreObjects.toStringHelper的实现

     public static ToStringHelper toStringHelper(Object self) {
        return new ToStringHelper(simpleName(self.getClass()));
      }

    静态方法直接返回ToStringHelper对象,接下来链式调用add(name,value)方法,而ToStringHelper内部维护一个ValueHolder(name, value,next结构)链表,记录add(name,value)的所有内容

    public static final class ToStringHelper {
        private final String className;
        private ValueHolder holderHead = new ValueHolder();
        private ValueHolder holderTail = holderHead;
        private boolean omitNullValues = false;
    }
    private ToStringHelper addHolder(String name, @Nullable Object value) {
        ValueHolder valueHolder = addHolder();
        valueHolder.value = value;
        valueHolder.name = checkNotNull(name);
        return this;
    }

    还有一个方法。简单说明一下,代码如下:

    public ToStringHelper omitNullValues() {
          omitNullValues = true;
          return this;
    }

    这里omitNullValues是一个开关,控制是否在ToStringHelper.toString()的时候输出null值。

    另一个就是对于compare的重写,这个实现的很是巧妙

    @Override
    public int compareTo(Person o) {
      return ComparisonChain.start().compare(id, o.id).compare(name, o.name).compare(age, o.age).result();
    }

    在ComparisonChain中,有三个内部常量

    private static final ComparisonChain ACTIVE = new ComparisonChain();
    private static final ComparisonChain LESS = new InactiveComparisonChain(-1);
    private static final ComparisonChain GREATER = new InactiveComparisonChain(1);

    在ACTIVE实现中,才真正实现了compare的比较逻辑是就是classify()方法

    ComparisonChain classify(int result) {
          return (result < 0) ? LESS : (result > 0) ? GREATER : ACTIVE;
    }

    LESS和GREATER的区别仅仅在于,构造参数中传入的int(result)值不同,而在InactiveComparisonChain内部实现中,compare方法仅仅返回this,而不去真正执行比较逻辑,因为此阶段的比较结果如果是LESS或是GREATER,最终ComparisonChain的结果也就决定了。而后续的比较没有意义。

     private static final class InactiveComparisonChain extends ComparisonChain {
        final int result;
    
        InactiveComparisonChain(int result) {
          this.result = result;
        }
        @Override public ComparisonChain compare(
            @Nullable Comparable left, @Nullable Comparable right) {
          return this;
        }
        @Override public <T> ComparisonChain compare(@Nullable T left,
            @Nullable T right, @Nullable Comparator<T> comparator) {
          return this;
        }
        @Override public ComparisonChain compare(int left, int right) {
          return this;
        }
        @Override public ComparisonChain compare(long left, long right) {
          return this;
        }
        @Override public ComparisonChain compare(float left, float right) {
          return this;
        }
        @Override public ComparisonChain compare(double left, double right) {
          return this;
        }
        @Override public ComparisonChain compareTrueFirst(boolean left, boolean right) {
          return this;
        }
        @Override public ComparisonChain compareFalseFirst(boolean left, boolean right) {
          return this;
        }
        @Override public int result() {
          return result;
        }
      }
  • 相关阅读:
    Spring Cloud(面试必备):服务雪崩、降级与熔断
    SpringCloud 分布式事务解决方案
    2020年3月25java现场面试(有点料)
    SpringCloud Feign工作原理
    MySQL数据库引擎详解
    MySQL Hardware--CentOS 6修改CPU性能模式
    MySQL Hardware--网络测试
    MySQL Execution Plan--EXPLAIN用法
    MySQL Event--Event and EventScheduler
    MySQL Error--Error Code
  • 原文地址:https://www.cnblogs.com/pona/p/4533051.html
Copyright © 2011-2022 走看看