码迷,mamicode.com
首页 > 其他好文 > 详细

重写equals和hashCode方法的示例

时间:2015-03-01 23:55:07      阅读:352      评论:0      收藏:0      [点我收藏+]

标签:

如果一个类有自己特有的“逻辑相等”,且需要以此进行比较时,那么就需要重写equals方法。

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

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

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

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

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


有个示例对象如下:

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

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

@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;
	}


重写equals和hashCode方法的示例

标签:

原文地址:http://my.oschina.net/u/1756290/blog/381095

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!