原文地址:http://blog.csdn.net/zzcchunter/article/details/7463913
HashSet 添加元素,首先比较hash值 是否有相同hash,没有则添加成功,有则继续比较equals,如果不同则添加成功,否则不添加。
测试方法,使用一个Java Bean的person类,有name和age两个域,覆写public boolean equals(Object obj) 和public int hashCode() 两个方法,覆写方法中都添加一句输出语句,测试是否该方法被调用/
person类:
- package info.dyndns.oszc;
- public class Person {
- public String name;
- public int age;
- public Person(String name, int age)
- {
- this.name = name;
- this.age = age;
- }
- public void print(){
- System.out.println(name + age);
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String toString(){
- return getName() +".." + getAge();
- }
- @Override
- public boolean equals(Object obj) {
- System.out.println("调用equals方法"); //这里打印为了看清程序是否调用了equals方法
- if( !(obj instanceof Person)){
- return false;
- }
- Person p =(Person) obj;
- return getName().equals(p.getName()) && getAge()==p.getAge();
- }
- @Override
- public int hashCode() {
- System.out.println("调用hashCode方法,hash为:"+ getName().hashCode() + getAge()*9); //这里打印为了看清程序是否调用了equals方法
- return getName().hashCode() + getAge()*9;
- }
- }
工具类
- package info.dyndns.oszc;
- import java.util.*;
- public class Utils {
- public static <E>void print(E e)
- {
- System.out.println(e);
- }
- public static <E>void printElements(Collection<E> al)
- {
- Iterator<E> it = al.iterator();
- while (it.hasNext()){
- print(it.next());
- }
- }
- public static <E>void put (Collection al,E e)
- {
- if (!al.contains(e))
- al.add(e);
- }
- }
测试类,首先添加两个不同的元素
- package info.dyndns.oszc;
- import java.util.HashSet;
- public class HashSetTest {
- public void test(){
- HashSet<Person> hs = new HashSet<Person>();
- hs.add(new Person("zs", 11));
- hs.add(new Person("ls", 12));
- Utils.printElements(hs);
- }
- public static void main(String[] args) {
- HashSetTest hst = new HashSetTest();
- hst.test();
- }
- }
output:
- 调用hashCode方法,hash为:389799
- 调用hashCode方法,hash为:3463108
- ls..12
- zs..11
显然调用了两次hashcode方法,由于hash值不同,所以没有调用equals方法。
然后我们添加两遍同一个元素:
- package info.dyndns.oszc;
- import java.util.HashSet;
- public class HashSetTest {
- public void test(){
- HashSet<Person> hs = new HashSet<Person>();
- hs.add(new Person("zs", 11));
- hs.add(new Person("zs", 11));
- Utils.printElements(hs);
- }
- public static void main(String[] args) {
- HashSetTest hst = new HashSetTest();
- hst.test();
- }
- }
output:
- 调用hashCode方法,hash为:389799
- 调用hashCode方法,hash为:389799
- 调用equals方法
- zs..11
可以看出当hash值相同时,equals方法会被调用,当他们都相同,则hashset判断两个元素完全一致,所以后一个元素未能加入到hashset集合中。
所以我们在自定义类要添加到hashset中时候,务必重写以上两个方法,来保证hashset添加元素的唯一性。