`

hashCode、hashCode()与HashSet集合

    博客分类:
  • java
 
阅读更多

hashCode、hashCode()与HashSet集合  

2010-01-25 22:58:43|  分类: Java Se |  标签: |字号 订阅

 hashCode

当使用toString方法的时候返回一个 "类型名@#$%#^%$ "的东西,比如一个****@4e57de。"@ "前面的是你的类名,后面的就是散列码的16进制表示。

hashCode 叫哈希代码或称散列码,简单的说就是通过哈希算法算出来的一大窜数字之类的东西和内存有关。默认的实现是将对象内部地址转化为整数作为HashCode,这当然能保证每个对象具有不同的HasCode,因为不同的对象内部地址肯定不同(废话)。因此你可以简单理解为对象在内存中的地址 担不是绝对物理地址。

hashCode()

Java中的集合(Collection)有两类,一类是List,再有一类是Set。前者集合内的元素是有序的,元素可以重复;后者元素无序,但元素不可重复。

那么这里就有一个比较严重的问题了:要想保证元素不重复,可两个元素是否重复应该依据什么来判断呢?

当我们向HashSet集合中添加元素时,它是按hash算法来存储集合中的元素。首先HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据该hashCode值决定该对象在HashSet中的存储位置。如果两个元素通过equals方法比较返回true,但它们的hashCode()方法返回值不相等,HashSet将会把它们存储在不同位置,也就添加成功。

简单的说,HashSet集合判断两个元素的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值也相等。看下面例子:

import java.util.*;

//类A的equals方法总是返回true,但没有重写其hashCode()方法

class A{

     public boolean equals(Object obj){

          return true;

     }

}

//类B的hashCode()方法总是返回1,但没有重写其equals()方法

class B{

     public int hashCode(){

          return 1;

     }

}

//类C的hashCode()方法总是返回2,但没有重写其equals()方法

class C{

     public int hashCode()    {

          return 2;

     }

     public boolean equals(Object obj)   {

          return true;

     }

}

public class TestHashSet{

     public static void main(String[] args){

          HashSet books = new HashSet();

          //分别向books集合中添加2个A对象,2个B对象,2个C对象

          books.add(new A());

          books.add(new A());

          books.add(new B());

          books.add(new B());

          books.add(new C());

          books.add(new C());

          System.out.println(books);

     }

}

运行上面的程序,看到如下运行结果:

[B@1,B@1,C@2,A@c17164, A@de6ced]

从上面的程序可以看出,即使两个A对象通过equals比较返回true,但HashSet依然把它们当成2个对象;即使2个B对象的hashCode()返回相同的值(都是1),HashSet依然会把它们当成2个对象。

总结:如果需要某个类的对象保存到HashSet集合中,重写这个类的equals()方法和hashCode()方法,应该尽量保证两个对象通过equals比较返回true时,它们的hashCode方法返回值也是相等.

为什么会先调hashCode()方法呢?

大家可以想想,如果集合中现在已经有1000个元素,那么第1001个元素加入集合时,它就要调用1000次equals方法。这显然会大大降低效率。

通过hashCode()方法返回的是hashcode码。这样一来,当集合要添加新的元素时,先调用这个元素的hashCode()方法,就一下子能定位到它应该放置的物理位置上。如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如果这个位置上已经有元素了,就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。所以这里存在一个冲突解决的问题。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。

分享到:
评论

相关推荐

    Java基础加强_ArrayList_HashSet的比较及Hashcode分析

    Java基础加强_ArrayList_HashSet的比较及Hashcode分析

    重写hashCode()和equals()方法详细介绍

    主要介绍了重写hashCode()和equals()方法详细介绍,涉及重写equals()方法,重写hashCode()方法,重写equals()而不重写hashCode()的风险等相关内容的介绍,具有一定借鉴价值,需要的朋友可以参考下

    HashCode作用_动力节点Java学院整理

    Java集合中有两类,一类是List,一类是Set他们之间的区别就在于List集合中的元素师有序的,且可以重复,而Set集合中元素是无序不可重复的。对于List好处理,但是对于Set而言我们要如何来保证元素不重复呢?通过迭代...

    equals 和 hashCode两者效果分析详解.docx

    原因是因为,在Java自带的容器HashMap和HashSet中, 都需同时要用到对象的hashCode()和equals()方法来进行判断,然后再插入删除元素,这点我们一会再谈。 那么我们还是单独来看hashCode(),为什么HashMap需要用到...

    实验05 Java集合.doc

    3)对集合进行遍历,分别打印集合中的每个元素的位置与内容; 4)打印集合的大小,然后删除集合中的第3个元素,并显示删除元素的内容,然后再打印目前集合中第3个元素的内容,并再次打印集合的大小。 3、编写程序...

    java集合知识-map、set等

    记住:如果元素要存储到HashSet集合中,必须覆盖hashCode方法和equals方法。 一般情况下,如果自定义的类会产生很多对象,比如人,学生,书,通常都需要覆盖equals,hashCode方法。 建立对象判断是否相同的依据。...

    Java提高篇之hashCode

    在前面三篇博文中LZ讲解了(HashMap、HashSet、HashTable),在其中LZ不断地讲解他们的put和get方法,在这两个方法中计算key的hashCode应该是重要也是精华的部分,所以下面LZ揭开hashCode的“神秘”面纱。...

    HashSet,TreeSet和LinkedHashSet的区别1

    简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相 等注意,如果要把一个对

    set集合的基本特点,set集合底层去重原理,集合怎么进行排序

    set集合是无序的相较于list集合是没有下标的,hashset底层去重,与hashCode、equals方法相关,排序的元素不是String,而是对象Person

    HashSet和HashMap的区别_动力节点Java学院整理

    HashSet实现了Set接口,它不允许集合中有重复的值,当我们提到HashSet时,第一件事情就是在将对象存储在HashSet之前,要先确保对象重写equals()和hashCode()方法,这样才能比较对象的值是否相等,以确保set中没有...

    软件构造心得(10):编写等价性判断时重写Hashcode的原因:理论与性能分析

    一句话概括,因为我们要保证,在我们的ADT被使用hash值作为hashset等数据结构的部分时(绝大多数情况这是不可被避免的),避免由于预设的hash值(预设的是地址,unpredictable)和我们判定两个对象等价的

    jdk 的集合框架的主体结构

    jdk 的集合框架的主体结构: Set 成员不能重复 HashSet 外部无序地遍历成员。 成员可为任意Object子类的对象,但如果覆盖了equals方法,同时注意修改hashCode方法。

    大厂真题之阿里云-Java实习生

    HashSet 是如何保证不重复的 向 HashSet 中 add ()元素时...重复( HashMap 比较key是否相等是先比较 hashcode 在比较 equals )。 HashMap 是线程安全的吗,为什么不是线程安全的(最好画图说明多线程 环境下不安全)?

    java8集合源码分析-CollectionDemo:自己复习集合框架时候的例子

    集合源码分析 java基础复习 [TOC] 一、集合 1.Iterator 2.Collection 2.1 List--->有序、有索引、元素可重复 1.ArrayList: 底层是数组结构、查询快、增删慢、不同步 添加第一个元素的时候,创建默认个数是10个,...

    【后端】java基础(4.2)java中级基础之集合——List

    HashSet的底层结构是哈希表,主要用于快速查找,存入HashSet的对象必须定义HashCode。不能保证保存次序 TreeSet底层为树状结构,可以保证保存次序 LinkedHashSet具有HashSet的速度,且底层使用链表维护元素的次序。 ...

    Java期末复习-类集框架

    List接口、ArrayList类、Vector类、栈操作类Stack、链表操作类LinkList、队列操作接口Queue、Set接口、HashSet类、TreeSet类、SortedSet接口 双值操作接口Map(key->value)及其子接口、子类: SortedMap接口、HashMap...

    【Java】常用数据集合体系和特点(汇总)

    Collection体系集合1.1 List 表① ArrayList 类(数组)② Vector 类(数组、线程同步)③ LinkedList 类(链表)④ CopyOnWriteArrayList 类(线程安全且高效的List)1.2 Set 集合① HashSet 类(HashCode)② ...

    Java面试题.docx

    31、HashSet与HashMap怎么判断集合元素重复? 33、ArrayList和LinkedList的区别,以及应用场景 34、数组和链表的区别 35、开启线程的三种方式? 36、线程和进程的区别? 38、run()和start()方法区别 39、如何...

    architect-awesome-code

    数据结构java队列——queue详细解析Queue:先进先出(FIFO)的数据结构。与List、Set同一级别,都是继承了Collection接口。LinkedList、...元素的哈希值通过元素的hashCode()方法来获取,hashSet首先会

    程序员需要经常刷题吗-simple-java-zh-CN:SimpleJava是Java常见问题的集合。中文翻译

    hashCode() 和 equals() 之间的契约 Java是按引用还是按值传递对象? 迭代与递归 ##3。 类和接口 什么是实例初始化器? 字段不能被覆盖? 继承与组合 如何使用 Java 枚举? 有多少种内部类? 什么是内部接口? 子类...

Global site tag (gtag.js) - Google Analytics