java复合主键 以及 重写hashCode 和 equals

使用主键的情况一般是 当缓存一组数据,而该数据中一个字段无法做到唯一性,So 声明个对象,将多个字段组合起来,作为缓存KEY。

 

如果该缓存使用 HashMap  实现;

考虑到HashMap 里存储N个对象后。 利用对象KEY直接取对应的值,我们会获取不到对应的值。

 

这就关系HashMap 内部 get(Key)获取机制了,里面是先获取 该Key 的hashCode() ,而后计算出Hash码,

再去获取对应对象的索引,找到该对象后,对比Hash码是否相等 以及 Equals 当前Key ,与 HashMap内对应的Key ,是否相等,对象与对象比较不是简单的值与值 结果:false。

 

那么基于以上情况.我们就有必要 重写 该Key 对象的 hashCode 和 equals 方法。

使得它们的 HashCode 和 equals 都相等。

 

使用Eclipse IDE 内就有自动生成机制

右键类编辑器 --> Source --> Generate hashCode() and equals()

 

PS:

HashMap源码 --> 构造函数

int loadFactor = 0.75;

this.loadFactor = loadFactor; //加载系数因子
threshold = (int)(capacity * loadFactor);  //初始容量*系数因子

容器内部每当容量达到threshold 后将自动*2增长容量?貌似。

 

1.两个对象equals相等那么hashcode 是一定相等的。

2.两个对象equals不相等hashcode可能相等可以不相等。

因为hashCode说白了是地址值经过一系列的复杂运算得到的结果,而Object中的equals方法底层比较的就是地址值,所以equals()相等,hashCode必定相等,反equals()不等,在java底层进行哈希运算的时候有一定的几率出现相等的hashCode,所以hashCode()可等可不等。

 

public class SunDy {
	
	public SunDy(){}
	
	public SunDy(Integer id,Integer age){
		this.id = id;
		this.age = age;
	}
	
	private Integer id;
	
	private Integer age;
	
	/**
	 * prime = 31 ; 为什么使用31?  :
	 * 选择31原因是因为31是一个素数,存储数据计算hash地址的时候,我们希望尽量减少有同样的hash地址,所谓“冲突”。
	 * 如果使用相同hash地址的数据过多,那么这些数据所组成的
	 * hash链就更长,从而降低了查询效率!所以在选择系数的时候要选择尽量长的系数并且让乘法尽量不要溢出的系数,
	 * 因为如果计算出来的hash地址越大,所 谓的“冲突”就越少,查找起来效率也会提高.
	 * 31可以 由i*31== (i<<5)-1来表示,现在很多虚拟机里面都有做相关优化,使用31的原因可能是为了更好的分配hash地址,并且31只占用5bits!
	 * 在java乘法中如果数字相乘过大会导致溢出的问题,从而导致数据的丢失.
	 * 而31则是素数(质数)而且不是很长的数字,最终它被选择为相乘的系数的原因不过与此.
	 * PS: 隐隐记得那篇博客也提到过,是为了不让它为负数?
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((age == null) ? 0 : age.hashCode());
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		SunDy other = (SunDy) obj;
		if (age == null) {
			if (other.age != null)
				return false;
		} else if (!age.equals(other.age))
			return false;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
	
	
	
}

 

 

 

 

   另外网上搜索其他博文讲的比较细致的有:

  1.Java 中正确使用 hashCode 和 equals 方法    [ or http://www.oschina.net/question/82993_75533]

   2.关于java HashCode 内使用31系数问题

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值