重写equals和hashCode方法的示例

若是一个类有本身特有的“逻辑相等”,且须要以此进行比较时,那么就须要重写equals方法。java

在Object的规范中,重写equals方法有下面几条通用约定:缓存

  • 自反性。 x.equals(x) == trueide

  • 对称性。if   y.equals(x) == true , then  x.equals(y) == true性能

  • 传递性。if   x.equals(y) == true y.equals(x) == true , then x.equals(z) == truecode

  • 一致性。若是比较的对象没有被修改,那么屡次调用equals方法返回的结果应该相同
    对象


有个示例对象以下:
hash

public class Book {
	private long id;
	private String name;
	private boolean isPublished;
}

那么重写的equals方法示例以下:
class

@Override
	public boolean equals(Object obj) {
		if( !(obj instanceof Book))
			return false;
		Book b = (Book) obj;
		return b.id == id 
				&& b.isPublished == isPublished 
				&& (b.name == name || (b != null && b.equals(b.name)) );
	}



在重写了equals方法的类中,若是不重写hashcode方法,则全部基于hash的集合就无法正常使用。方法

重写hashCode方法示例以下:集合

@Override
	public int hashCode() {
		int hashCode = 3;
		hashCode = 31 * hashCode + (int)(id ^ (id>>>32));
		hashCode = 31 * hashCode + (name == null?0:name.hashCode());
		hashCode = 31 * hashCode + (isPublished?1:0);
		return hashCode;
	}



若是这个类是不可变的,而且hashCode比较耗性能,则能够考虑缓存hashCode的值。

示例以下:

        //使用volatile保证可见性
        private volatile int hashCodeCache;
	
	@Override
	public int hashCode() {
		int hashCode = hashCodeCache;
		if(hashCode == 0){
			hashCode = 3;
			hashCode = 31 * hashCode + (int)(id ^ (id>>>32));
			hashCode = 31 * hashCode + (name == null?0:name.hashCode());
			hashCode = 31 * hashCode + (isPublished?1:0);
			hashCodeCache = hashCode;
		}
		return hashCode;
	}
相关文章
相关标签/搜索