JSL规定,调用两个Equals的对象,其hashCode必须相等。
假如我们没有覆盖hashCode,则在和集合类对象HashMap、HashSet、和HashTable一起使用时,会出现问题。例子所示:
public class Money {
private BigDecimal ammount;
private String unit;
public Money(BigDecimal ammount, String unit){
this.ammount= ammount;
this.unit = unit;
}
public BigDecimal getAmmount() {
return ammount;
}
public void setAmmount(BigDecimal ammount) {
this.ammount = ammount;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Money)) {
return false;
}
Money m = (Money) o;
return (ammount == null) || ammount.equals(m.getAmmount()) && (unit == null) || unit.equals(m.getUnit());
}
}
在执行如下测试方法时会发现,print的结果为null
public static void main(String[] args) {
Map m = new HashMap();
m.put(new Money(new BigDecimal(10),"CNY"), 1);
System.out.println(m.get(new Money(new BigDecimal(10),"CNY")));
}
这是因为在Map的get方法中,调用了key的hashCode,如下:
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}
不覆盖的情况下会直接用object的hashCode,不会产生正确结果。即hash算法把对象放在一个散列桶里,而get方法却从另一个散列桶取值。
如果在Money类里加上如下散列方法:
@Override
public int hashCode() {
int h=17;
h= 31*h+ ammount.hashCode();
h= 31*h+ unit.hashCode();
return h;
}
运行test,则可以得到正确结果:1
至于为什么使用这种hash散列,这里借鉴了经典hash算法的规则,有一点需要强调,能够运用JVM直接完成的算法(移位等)则要使用这些能够提高速度的方法。*31正是运用了新JVM的特性 他可以转换为 (i<<5)-i
分享到:
相关推荐
Java重写equals同时需要重写hashCode的代码说明,以及如何重写hashCode方法,此代码演示按照effective java书籍说明的重写思路。代码中演示了使用集合存储对象,并且对象作为key,需重写equals和hashCode.
equals()和hashcode()这两个方法都是从object类中继承过来的。当String 、Math、还有Integer、Double。。。。等这些封装类在使用equals()方法时,已经覆盖了object类的equals()方法.
重写equals和hashcode方法,学习和进步
本文介绍了Java语言不直接支持关联数组,可以使用任何对象作为一个索引的数组,但在根Object类中使用 hashCode()方法明确表示期望广泛使用HashMap。理想情况下基于散列的容器提供有效插入和有效检索;直接在对象模式...
这里是一个文档,里边讲解了hashCode与equals方法使用,大家要是不明白,可以去看看
更清楚的了解hashcode()和equals()方法。
Java解惑系列之一--equals和==之间究竟有什么区别 稍微学过一些java的同学都可能在网络上看到这样的一道题: 在java语言当中,equals和==之间究竟有什么区别? 而这道题的答案也是千篇一律: equals是用来比较对象...
计算机后端-Java-Java核心基础-第24章 集合01 23. 关于hashCode()和equals()的重写.avi
Java equals 方法与hashcode 方法的深入解析.rar
1.概述 2.为什么重写equels方法要重写hashcode方法 3.例子
retry.zip,用于异步重试scala futures的简单原语库,因为您不应该放弃,至少在第一次尝试时不应该放弃。
NULL 博文链接:https://zpointer.iteye.com/blog/1058337
equals():反映的是对象或变量具体的值,即两个对象里面包含的值--可能是对象的引用,也可能是值类型的值。 hashCode():计算出对象实例的哈希码,并返回哈希码,又称为散列函数。根类Object的hashCode()方法的...
HashCode相同equals不同的2位字符集合算法 另附ASCII码表
解析Java对象的equals()和hashCode()的使用
hashCode()和equals()定义在Object类中,这个类是所有java类的基类,所以所有的java类都继承这两个方法。 使用hashCode()和equals() hashCode()方法被用来获取给定对象的整数。这个整数被用来确定对象被...
本文档详细介绍了set接口为什么会用到hashCode和equals方法以及这两个方法的一些探讨 set不同的实现类用到的这两个方法也不同
为什么重写equals方法,还必须要重写hashcode方法
主要介绍了Java 覆盖equals时总要覆盖hashcode的相关资料,这里附有实例代码,具有参考价值,需要的朋友可以参考下
hashCode()和equals()定义在Object类中,这个类是所有java类的基类,所以所有的java类都继承这两个方法。下面这篇文章主要给大家介绍了关于java中hashCode、equals的使用方法,需要的朋友可以参考下。