package com.wangzhu.map;

import java.util.HashMap;

/**
* hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,<br/>
* 这样的散列集合包括HashSet、HashMap以及HashTable。<br/>
* 能否可以直接根据hashCode值判断两个对象是否相等呢?<br/>
* 答案:肯定是不可以的,因为不同的对象可能会生成相同的hashCode值。<br/>
* 虽然不能根据hashCode值判断两个对象是否相等,但是可以直接根据hashCode值判断两个对象不等,<br/>
* 如果两个对象的hashCode值不等,则必定是两个不同的对象。如果要判断两个对象是否真正相等,则必须通过equals方法。<br/>
* 也就是说对于两个对象,如果调用equals方法得到的结果为true,则两个对象的hashCode值必定相等。<br/>
* 如果equals方法得到的结果为,则两个对象的hashCode值不一定不同; <br/>
* 如果两个对象的hashCode值不等,则equals方法得到的结果必为;<br/>
* 如果两个对象的hashCode值相等,则equals方法得到的结果未知。<br/>
*
* @author wangzhu
* @date 2015-2-1下午11:22:42
*
*/
public class DemoMap2 { /**
* @param args
*/
public static void main(String[] args) {
Student stu = new Student(21, "John");
HashMap<Student, Integer> map = new HashMap<Student, Integer>();
map.put(stu, 1);
System.out.println(map.get(stu));//
System.out.println(map.get(new Student(21, "John")));//
/**
* 若Student只重写equals方法而没有没有重写hashCode方法时,则输出为null
*/ stu.setAge(22);
System.out.println(map.get(stu));// null
/**
* 在程序执行期间,只要equals方法的比较操作用到的信息没有被修改,<br/>
* 那么对这同一个对象调用多次, hashCode方法必须始终如一地返回同一个整数。<br/>
*
* 设计hashCode()时最终稿的因素就是:无论何时,对同一个对象调用hashCode()都应该产生同样的值。<br/>
* 如果在将一个对象用put()添加进HashMap时产生一个hashCode值,而用get()取出时却产生另一个hashCode值,<br/>
* 那么就无法获取该对象了。所以如果你的hashCode方法依赖于对象中易变的数据,用户就要当心了,<br/>
* 因为此数据变化时,hashCode() 方法就会生成一个不同的散列码。<br/>
*/
} } class Student {
int age;
String name; public Student(int age, String name) {
super();
this.age = age;
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = (prime * result) + age;
result = (prime * result) + ((name == null) ? 0 : name.hashCode());
return result;
} /**
* 重写时,需要让equals方法与hashCode方法始终在逻辑上保持一致性。
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (this.getClass() != obj.getClass()) {
return false;
}
Student other = (Student) obj;
if (age != other.age) {
return false;
}
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
return true;
} }

下面是HashMap中的put方法【JDK1.6】

    public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
} modCount++;
addEntry(hash, key, value, i);
return null;
}

备注:put方法是用来向HashMap中添加新的元素。从put方法的具体实现可知,其会先调用hashCode方法得到该元素的hashCode值【经过处理的】,然后查看其是否存在于table数组中,如果存在则调用equals方法来确定是否是存在该元素;如果存在,则更新value值,否则将新的元素添加到HashMap中。

下面是HashMap中的get方法【JDK1.6】

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

备注:get方法是用来将HashMap中对应Key的值Value取出来。从get方法的具体实现可知,其会先调用hashCode方法得到该元素的hashCode值,然后查看其在table数组中是否存在,如果存在则调用equals方法来确定是Key对应的元素,并返回其Value,否则返回null。

重写equals()方法时,需要同时重写hashCode()方法的更多相关文章

  1. 第九条:覆盖equals方法时总要覆盖hashCode方法

    Object类的hashCode方法: public native int hashCode();   是一个本地方法. 其中这个方法的主要注释如下: Whenever it is invoked o ...

  2. 【Java实战】源码解析为什么覆盖equals方法时总要覆盖hashCode方法

    1.背景知识 本文代码基于jdk1.8分析,<Java编程思想>中有如下描述: 另外再看下Object.java对hashCode()方法的说明: /** * Returns a hash ...

  3. 半夜思考, 为什么建议重写 equals() 方法时, 也要重写 hashCode() 方法

    我说的半夜, 并不是真正的半夜, 指的是在我一个人的时候, 我会去思考一些奇怪的问题. 要理解 hashCode() 需要理解下面三个点: hash契约 哈希冲突 哈希可变 第一点: hash 契约指 ...

  4. 覆写equals方法为什么需要覆写hashCode方法

    覆写equals方法必须覆写hashCode方法,是JDK API上反复说明的,不过为什么要这样做呢?这两个方法之间有什么关系呢? void test() { // Person类的实例作为Map的k ...

  5. 在IE浏览器中执行OpenFlashChart的reload方法时无法刷新的解决方法

    由于项目需求,需要在网页上利用图表展示相关数据的统计信息,采用了OpenFlashChart技术.OpenFlashChart是一款开源的以Flash和Javascript为技术基础的免费图表,用它能 ...

  6. 第八条——覆盖equals方法时需遵守的通用约定

    1)自反性 对于任何非null的引用值x,x.equals(x)必须返回true.---这一点基本上不会有啥问题 2)对称性 对于任何非null的引用值x和y,当且仅当x.equals(y)为true ...

  7. 为什么重写equals时必须重写hashCode方法?

    原文地址:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452206.html 首先我们先来看下String类的源码:可以发现Stri ...

  8. 为什么重写equals时必须重写hashCode方法?(转发+整理)

    为什么重写equals时必须重写hashCode方法? 原文地址:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452206.html ...

  9. Effective Java 第三版——11. 重写equals方法时同时也要重写hashcode方法

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  10. why在重写equals时还必须重写hashcode方法

    首先我们先来看下String类的源码:可以发现String是重写了Object类的equals方法的,并且也重写了hashcode方法 public boolean equals(Object anO ...

随机推荐

  1. Android Audio Play Out Channel

    1: 7嘴8舌 扬声器, 耳机, 和听筒 就是通过: audiomanager.setmode(AudioManager.MODE_IN_COMMUNICATION)audiomanager.setS ...

  2. window store app 附件读取

    public static async Task<bool> DisplayApplicationPicker(string folderName, string fileName) { ...

  3. memcached/redis安全性

    最近看到说redis,memcached服务器安全的问题,想想也是,使用这两种服务N年了,由于历史问题吧,工作中基本是以memcached为主,后来才慢慢引入运用redis.由于memcached是没 ...

  4. 【Delphi】圆角窗体

    procedure TForm1.FormCreate(Sender: TObject); var hr :thandle; begin hr:=createroundrectrgn(1,1,widt ...

  5. Boa练习程序2

    做一个地址簿的gui. #Boa:Frame:AddressEntry import wx def create(parent): return AddressEntry(parent) [wxID_ ...

  6. thinkpad t440p 解决无线网卡驱动

    $ wget https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1239578/+attachment/4057550/+files/rtl_9 ...

  7. ActiveMQ之MessageListener

    消息的消费者接收消息可以采用两种方式: 1.consumer.receive()或 consumer.receive(int timeout); 2.注册一个MessageListener. 采用第一 ...

  8. jQuery对象和DOM对象的互相转换【 转】

    jQuery对象转换为dom对象 只有jQuery对象才能调用jQuery类库的各种函数,同样有些dom对象的属性和方法在jQuery上也是无法调用的,不过基本上jQuery类库提供的函数包含了所有的 ...

  9. linux下gcc编译的参数详细说明

    参考网址:1 http://hi.baidu.com/zengzhaonong/item/f1f9383565fa5c302e0f8125 gcc使用方法 汇总 2 http://s99f.blog. ...

  10. macos port总结

    http://stackoverflow.com/questions/733951/unable-to-download-the-source-code-of-open-source-projects ...