guava 常用对象方法

介绍下guava提供的一些便利的针对对象的操作,这些操作提高了代码的简洁性和可读性

equals

现在有个User类如下所示

class User{

    private int age;
    private String name;
    private Date birthday;
    ...省略get/set
}

如果要重写这个类的equals方法,通常会这样做

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        if (age != user.age) return false;
        if (name != null ? !name.equals(user.name) : user.name != null) return false;
        return !(birthday != null ? !birthday.equals(user.birthday) : user.birthday != null);
    }

可以看出针对引用类型的namebirthday。都要比较一下null的情况。代码有些啰嗦,不够简洁
name != null ? !name.equals(user.name) : user.name != null

针对这个情况,guava提供了Objects.equal(Object,Object)方法,使用guava后的写法如下:

    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return age == user.age &&
                Objects.equal(name, user.name) && //使用Objects.equal
                Objects.equal(birthday, user.birthday);
    }

可以看到使用Objects.equal方法增加代码的可读性和简洁性 。其实Objects.equal方法内部也是走的同样的判断逻辑,源码如下:

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

hashcode

还是用先前的User类,如果要重写hashCode方法,通常做法如下:

    public int hashCode() {
        int result = age;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        result = 31 * result + (birthday != null ? birthday.hashCode() : 0);
        return result;
    }

如果用guava,就是这样的:

    @Override
    public int hashCode() {
        return Objects.hashCode(age, name, birthday);
    }

guava的Objects.hashCode也会迭代传入的参数计算hash值,源码如下:

    public static int hashCode(Object a[]) {
        if (a == null) return 0;
        int result = 1;
        for (Object element : a) //循环参数,计算hash
            result = 31 * result + (element == null ? 0 : element.hashCode()); 
        return result;
    }

toString

重写对象的toString方法,在代码调试和日志记录的非常有用,重写UsertoString通常做法如下:

    public String toString() {
        final StringBuffer sb = new StringBuffer("User{");
        sb.append("age=").append(age);
        sb.append(", name='").append(name).append('\'');
        sb.append(", birthday=").append(birthday);
        sb.append('}');
        return sb.toString();
    }

看起来这一坨代码就乱,如果要去掉某个属性,也不好找。如果用guava就如下所示:

    public String toString() {
        return MoreObjects.toStringHelper(this)
                .add("age", age) //如果要去掉某个敏感的属性,直接删掉就可以了
                .add("name", name)
                .add("birthday", birthday)
                .toString();
    }

compare/compareTo

如果User实现了Comparable接口需要重写compareTo方法,通常写法如下:

    public int compareTo(User o) {
        int cmp = (age < o.age) ? -1 : ((age > o.age) ? 1 : 0);
        if (cmp != 0) {
            return cmp;
        }
        cmp = birthday.compareTo(o.birthday);
        if (cmp != 0) {
            return cmp;
        }
        return name.compareTo(o.name);
    }

出现错误也比较难定位,如果用guava,写法如下:

public int compareTo(User o) {
        return ComparisonChain.start()
                .compare(age, o.age)
                .compare(birthday, o.birthday)
                .compare(name, o.name)
                .result();
    }

ComparisonChain提供者中链式的编程风格,虽然这些属性的比较代码是连起来写的。但是是有“短路”规则的即:如果有一个compare操作返回值为非零,就不会执行后面的属性比较了。

默认值

有时候会遇到这样的逻辑:如果第一个值为null,就取默认值,否则就去第一个值。

String ret=serivce.operation();
return ret!=null?ret:"默认值";

在guava中可以用MoreObjects.firstNonNull(first,second)方法

String ret=serivce.operation();
return MoreObjects.firstNonNull(ret,"默认值");//使用MoreObjects.firstNonNull

不过MoreObjects.firstNonNull(first,second)中如果first和second都为null的时候就会抛出NPE(NullPointerException)异常

IDE的支持

IDE对这些也都有支持,以idea为例,可以选择guava的实现

  1. 按快捷键Alt+Insert
    这里写图片描述

  2. 选择guava的实现
    这里写图片描述

参照:
1、《getting started with google guava》
2、https://github.com/google/guava/wiki/CommonObjectUtilitiesExplained

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值