欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java基础(1) ---- hashCode

程序员文章站 2022-06-22 11:22:33
1、hashCode的概念 (1)hashCode方法是Object类的方法,在Java里所有类都默认继承Object类,即所有类都有hashCode方法。 (2)hashCode是jdk根据对象的存储地址算出来的一个int数字,即对象的哈希码值,代表了该对象在内存中的存储地址。 2、hashCod ......

1、hashCode的概念

(1)hashCode方法是Object类的方法,在Java里所有类都默认继承Object类,即所有类都有hashCode方法。

(2)hashCode是jdk根据对象的存储地址算出来的一个int数字,即对象的哈希码值,代表了该对象在内存中的存储地址

2、hashCode的作用

2.1、hashCode查找的快捷性

hashCode的存在主要是用于查找的快捷性,如HashTable、HashMap等,hashCode用来在散列存储结构中确定对象的存储地址(是存储地址,不是内存地址)。

2.2、HashSet不允许重复是如何实现的

比如,大家都知道HashSet是不允许重复的,HashSet有100个元素了,这时再add一个新元素。

(1)如果没有hashCode

就需要迭代100次,调用100次equals方法来判断该HashSet里是否已经存在这个新添加的元素。可想而知,效率是很低的。

(2)如果有hashCode

向HashSet添加一个新元素时,HashSet首先会调用hashCode方法,这样就可以定位到它的存储位置,若该处没有元素,则直接保存。如果该处已经有元素存在,就调用equals判断这两个元素内容是否相同,相同则不存,不同则散列到其它位置。这样处理,当我们向HashSet插入大量元素的时候就可以大大减少调用equals方法的次数,提高了效率。

2.3、HashSet集合和hashCode方法的代码示例

import java.util.HashSet;

public class Person {

	private int id;
	private String name;
	
	public Person(int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		
		//用于查看hashCode方法什么时候被调用,以及被调用的次数
		System.out.println("hashCode被调用, hashCode=" + result);
		
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		
		//用于查看equals方法什么时候被调用,以及被调用的次数
		System.out.println( "equals被调用了" );
		
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (id != other.id)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	
	public static void main(String[] args) {
		HashSet<Person> personHashSet = new HashSet<Person>();
		personHashSet.add(new Person(1, "张三"));
		personHashSet.add(new Person(2, "李四"));
		personHashSet.add(new Person(1, "张三"));
		System.out.println("personHashSet的长度是" + personHashSet.size());
	}
	
} 
hashCode被调用, hashCode=775881
hashCode被调用, hashCode=843084
hashCode被调用, hashCode=775881
equals被调用了
personHashSet的长度是2

每次向personHashSet添加一个Person时,都会调用hashCode方法,这样就可以直接定位该Person所存储的位置,若该处没有其它Person,则直接保存。若该处已经有Person存在,就调用equals方法来判断两个Person是否相同,相同则不存,不同则散列到其他位置。示例代码里,向personHashSet添加新元素时,hashCode方法无论如何都会被调用,所以hashCode方法被调用了三次。第1个Person和第3个Person的hashCode是相同的,添加第3个Person时才会去调用equals方法,所以equals方法被调用了一次。equals为true,相同则不存,所以personHashSet的长度是2。

(注:HashSet更详细的解读,会出现在本人后面的博文中,这里就不喧宾夺主本文的主题了。)

3、hashCode和equals的关系

(1)equals相等,hashCode一定相等。

(2)equals方法被重写,那么hashCode方法也应该被重写,并且产生hashCode使用的对象(类里面的属性),一定要和equals方法中使用的一致。

(3)hashCode相等,equals不一定相等。只能说明这两个对象在散列存储结构里(如Hashtable)“存放在同一个蓝子里”。