• Guava学习笔记(3)覆写Object的常用方法[翻译+学习笔记]


    Java的Object是所有类的父类, 也有几个常用的需要覆写的方法, 比如equals, hashCode和toString.

    每次写这几个方法都要做很多重复性的判断, 很多类库提供了覆写这几个方法的工具类, 比如apache commons lang.

    Guava也提供了类似的方式, 在JDK7也提供了和Guava类似的方法.

    equals

    equals是一个经常需要覆写的方法, 可以查看Object的equals方法注释, 对equals有几个性质的要求: 自反性reflexive, 对称性symmetric, 传递性transitive, 一致性consistent. 还有一个要求: 对于所有非null的值x, x.equals(null)都要返回false. (如果你要用null.equals(x)也可以, 会报NullPointerException)

    当我们要覆写的类中某些值可能为null的时候, 就需要对null做很多判断和分支处理. 使用Guava的Objects.equal方法可以避免这个问题, 使得equals的方法的覆写变得更加容易, 而且可读性强, 简洁.

    Objects.equal("a", "a"); // returns true
    Objects.equal(null, "a"); // returns false
    Objects.equal("a", null); // returns false
    Objects.equal(null, null); // returns true
    

     JDK7新引入了Objects类, 其中有类似的方法equals.

    hashCode

    要求equals返回true的值, hashCode也返回相同的值. 所以覆写equals方法, 一般都要覆写hashCode方法.

    写一个hashCode本来也不是很难, 但是Guava提供给我们了一个更加简单的方法--Objects.hashCode(Object ...), 这是个可变参数的方法, 参数列表可以是任意数量, 所以可以像这样使用Objects.hashCode(field1, field2, ..., fieldn).非常方便和简洁.

    JDK7新引入了Objects类, 其中有类似的方法hash.

    toString

    这个方法是用得最多的, 覆写得最多, 一个好的toString方法对于调试来说是非常重要的, 但是写起来确实很不爽. 幸好我们可以用eclipse的自动生成代码的功能, 也可以使用apache commons lang来自动生成(使用反射), 当然Guava也提供了方法.

       // Returns "ClassName{x=1}"
       Objects.toStringHelper(this)
           .add("x", 1)
           .toString();
    
       // Returns "MyObject{x=1}"
       Objects.toStringHelper("MyObject")
           .add("x", 1)
           .toString();
    

     commons lang的生成方式使用了反射, 效率可能会低一点, 但是有个好处, 修改了类中的成员变量, 不需要修改toString方法, 因为是用的反射. 这个还是很方便的.

    compare/compareTo

    实现Comparator或Comparable接口, 可以实现比较功能, 但是这个方法却并不好重写, 写过的人都知道. 为了简化, Guava提供了ComparisonChain.

    ComparisonChain是一个lazy的比较过程, 当比较结果为0的时候, 即相等的时候, 会继续比较下去, 出现非0的情况, 就会忽略后面的比较.

       public int compareTo(Foo that) {
         return ComparisonChain.start()
             .compare(this.aString, that.aString)
             .compare(this.anInt, that.anInt)
             .compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast())
             .result();
       }
    

     下面是一个完整的示例, 展示了这几个方法的使用

    import com.google.common.base.Objects;
    import com.google.common.collect.ComparisonChain;
    import com.google.common.collect.Ordering;
    
    public class Person implements Comparable<Person> {
    	public String name;
    	public String nickname;
    	public Gender gender;
    	
    	public Person(String name, String nickname, Gender gender) {
    		super();
    		this.name = name;
    		this.nickname = nickname;
    		this.gender = gender;
    	}
    	
    	@Override
    	public int hashCode() {
    		return Objects.hashCode(name, nickname);
    	}
    	
    	@Override
    	public boolean equals(Object obj) {
    		if (obj instanceof Person) {
    			Person that = (Person) obj;
    			return Objects.equal(name, that.name)
    					&& Objects.equal(nickname, that.nickname)
    					&& Objects.equal(gender, that.gender);
    		}
    		return false;
    	}
    //	@Override
    //	public String toString() {
    //		return Objects.toStringHelper(this)
    //				.add("name", name)
    //				.add("nickname", nickname)
    //				.add("gender", gender)
    //				.toString();
    //	}
    	@Override
    	public String toString() {
    		return Objects.toStringHelper(this)
    				.addValue(name)
    				.addValue(nickname)
    				.toString();
    	}
    	
    	public String preferredName() {
    		return Objects.firstNonNull(nickname, name);
    	}
    	
    	@Override
    	public int compareTo(Person that) {
    		return ComparisonChain.start()
    		         .compare(this.name, that.name)
    		         .compare(this.nickname, that.nickname)
    		         .compare(this.gender, that.gender, Ordering.natural().nullsLast())
    		         .result();
    	}
    	
    	public static void main(String[] args) {
    		Person person = new Person("Jack", "Jackson", Gender.MALE);
    		System.out.println(person);
    		Person person2 = new Person("Jack", "Jackson", Gender.FEMALE);
    		System.out.println(person2.compareTo(person));
    		System.out.println(person2.equals(person));
    	}
    }
    

     因本人水平有限, 欢迎拍砖!

    参考资料:

    1. 官方wiki: http://code.google.com/p/guava-libraries/wiki/GuavaExplained
    2. Object common methods: http://code.google.com/p/guava-libraries/wiki/CommonObjectUtilitiesExplained
  • 相关阅读:
    Vue学习手记01-安装和项目创建
    [Powershell] FTP Download File
    [PowerShell] Backup Folder and Files Across Network
    SSRS 请求并显示SharePoint人员和组字段
    Beta 冲刺 (2/7)
    Beta 冲刺 (1/7)
    BETA 版冲刺前准备
    事后诸葛亮
    Alpha 答辩总结
    α冲刺 (10/10)
  • 原文地址:https://www.cnblogs.com/icejoywoo/p/2571163.html
Copyright © 2020-2023  润新知