基础不牢固,一直不太明白hashCode是干啥的,惭愧惭愧。
刚在CSDN论坛上看到了一段解释,令我豁然开朗。
在存放集合这种数据的时候,我们可以选择List和Set两种形式,当然,Java当中它们不是具体的实现类.我们可以使用具体的实现类进行数据的存储.
但是List和Set的最显著区别,应该是,List可以放置相同的元素,Set只能放置不同的元素.也就是说Set里面的元素具有唯一性.
当然ArrayList和LinkedList也只是具体的实现形式不同了.我们也可以实现一个ArraySet或LinkedSet.但是.我们会发现一个比较严重的问题.就是.当我们向ArraySet(或LinkedSet)里面添加元素的时候,我们要逐个比较里面的所有已有元素.这样,当集合中数量非常多的时候,比较次数也会直线上升.也就是说,当我们结合中有10000个元素的时候,我再添加一个元素,要首先比较最多10000次才能确定我要添加的元素是否已经存在了,这会严重影响集合的性能.
为了更快捷的检索数据,我们才引进了hashCode的概念,每个Set里面的元素都会有一个hashCode的值,我们可以按照hashCode的值来存储集合里面的元素.如果要检索集合里面是否存在要添加的元素,只要先将该元素的hashCode值算出来,再到相应的位置进行查找,就可以了.对于相同hashCode的不同元素,我们把这个位置,按照链表的形式进行存放.这样,就可以很大程度上减少比较的次数.举个例子:
我们Set集合里面可能已经10000个不同的元素了.当添加新元素的时候,我们根据新元素的hashCode值,找到相应的位置,这个位置所对应的链表里面,可能只有五个元素,那么,我们只要比较5次,就可以判断整个集合中是否已经存在该元素了,因为,相同元素的hashCode一定是相同的.呵呵.为了使根据hashCode确定位置的速度更快,我们采用数组的下标来表示位置,数组里面存放链表.下标都是自然数,所以,要把hashCode进行向数组下标的映射转换(其实就是与运算).
最后,来谈谈,什么情况下重写hashCode,我们知道,自然情况下,hashCode所产生的值是很有规律的,这样的话,拥有10000个元素的Set,可能有9000个都在同一个位置上,这样,再加一个相同hashCode的元素时,那可能要比较90000次了.所以,我们要自己定义hashCode使得这些元素的hashCode在hashSet里面存储更加分散.不过Java的HashSet里面,已经有一个方法,将元素的hashCode做打散处理了,这个方法对于默认的hashCode还是比较有效果的.对于熟悉这些内容的程序员,为了程序的效率更高,可以重写hashCode方法.但是,不能使用随机数充当hashCode,每个元素,都应该对应唯一的一个hashCode,一个hashCode可以对应多个元素.
也可以这么说,只要对象内容一样,我们就有必要重写它的hashCode,hashCode代表的是对象的内存地址,或者说内存地址根据这个hash码得到, 一般的集合都重写了hashCode方法,而当我们自定义对象的时候就要重写hasdCode方法,保证内容一样的对象算出相同的hash码。hash码的用处只体现在需要散列的地方,如hashSet、hashMap,提高用户查找速度。
分享到:
相关推荐
Java基础加强_ArrayList_HashSet的比较及Hashcode分析
Java集合中有两类,一类是List,一类是Set他们之间的区别就在于List集合中的元素师有序的,且可以重复,而Set集合中元素是无序不可重复的。对于List好处理,但是对于Set而言我们要如何来保证元素不重复呢?通过迭代...
原因是因为,在Java自带的容器HashMap和HashSet中, 都需同时要用到对象的hashCode()和equals()方法来进行判断,然后再插入删除元素,这点我们一会再谈。 那么我们还是单独来看hashCode(),为什么HashMap需要用到...
主要介绍了重写hashCode()和equals()方法详细介绍,涉及重写equals()方法,重写hashCode()方法,重写equals()而不重写hashCode()的风险等相关内容的介绍,具有一定借鉴价值,需要的朋友可以参考下
在前面三篇博文中LZ讲解了(HashMap、HashSet、HashTable),在其中LZ不断地讲解他们的put和get方法,在这两个方法中计算key的hashCode应该是重要也是精华的部分,所以下面LZ揭开hashCode的“神秘”面纱。...
HashSet实现了Set接口,它不允许集合中有重复的值,当我们提到HashSet时,第一件事情就是在将对象存储在HashSet之前,要先确保对象重写equals()和hashCode()方法,这样才能比较对象的值是否相等,以确保set中没有...
HashSet 是如何保证不重复的 向 HashSet 中 add ()元素时,判断元素是否存在的依据,不仅要比较hash值,同时还要结合 equles 方法比较。 HashSet 中的 add ()方法会使用 HashMap 的 add ()方法。以下是 HashSet 部分...
简单的说,HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相 等注意,如果要把一个对
Java核心 该存储库将包含所有代码,并带有针对Java Core的少量注释。 有关更多信息,请参见和。 变更日志 带有实验室代码并针对以下每个课程进行测试: Java基础 ... HashMap / HashSet,hashCode()
1、编写程序练习将以下5个Person类的对象放在一个HashSet中。 姓名:张三 身份证号:178880001 姓名:王五 身份证号:178880002 姓名:李四 身份证号:178880003 姓名:王五 身份证号:178880002 姓名:李四 身份证...
记住:如果元素要存储到HashSet集合中,必须覆盖hashCode方法和equals方法。 一般情况下,如果自定义的类会产生很多对象,比如人,学生,书,通常都需要覆盖equals,hashCode方法。 建立对象判断是否相同的依据。...
一句话概括,因为我们要保证,在我们的ADT被使用hash值作为hashset等数据结构的部分时(绝大多数情况这是不可被避免的),避免由于预设的hash值(预设的是地址,unpredictable)和我们判定两个对象等价的
1、java中==和equals和hashCode的区别 2、int与integer的区别 3、String、StringBuffer、StringBuilder区别 4、什么是内部类?内部类的作用 5、进程和线程的区别 6、final,finally,finalize的区别 7、...
数据结构java队列——queue详细解析Queue:先进先出(FIFO)的数据结构。与List、Set同一级别,都是继承了Collection接口。LinkedList、...元素的哈希值通过元素的hashCode()方法来获取,hashSet首先会
HashSet实现了Set接口,它不允许集合中有重复的值,当我们提到HashSet时,第一件事情就是在将对象存储在HashSet之前,要先确保对象重写equals()和hashCode()方法,这样才能比较对象的值是否相等,以确保set中没有...
HashSet的底层结构是哈希表,主要用于快速查找,存入HashSet的对象必须定义HashCode。不能保证保存次序 TreeSet底层为树状结构,可以保证保存次序 LinkedHashSet具有HashSet的速度,且底层使用链表维护元素的次序。 ...
set集合是无序的相较于list集合是没有下标的,hashset底层去重,与hashCode、equals方法相关,排序的元素不是String,而是对象Person
List接口、ArrayList类、Vector类、栈操作类Stack、链表操作类LinkList、队列操作接口Queue、Set接口、HashSet类、TreeSet类、SortedSet接口 双值操作接口Map(key->value)及其子接口、子类: SortedMap接口、HashMap...
4. final 在 java 中有什么作用? 4 5. java 中的 Math.round(-1.5) 等于多少? 4 6. String 属于基础的数据类型吗? 4 7. java 中操作字符串都有哪些类?它们之间有什么区别? 4 8. String str="i"与 String str=...
jdk 的集合框架的主体结构: Set 成员不能重复 HashSet 外部无序地遍历成员。 成员可为任意Object子类的对象,但如果覆盖了equals方法,同时注意修改hashCode方法。