`
long_yu2
  • 浏览: 334528 次
社区版块
存档分类
最新评论

java 高新技术【5】ArrayList_HashSet的比较及Hashcode分析

 
阅读更多
只有类的实例对象要被采用哈希算法进行存储和检索时,这个类才需要按要求覆盖hashCode方法。即使程序可能暂时不会用到当前类的hashCode方法,但是为他提供一个hashCode方法也不会有什么不好,没准以后什么时候有用到这个方法了,所以,通常要求hashCode方法和equals方法一并被同时覆盖。

//HashSet比较时hashCode方法和equals方法都用了
HashSet:采用哈希算法的集合。实现了Collection接口,只能存入不同HashCode对象,即只存入不同的对象,如果希望存入具有相同内容的两个对象,则需覆盖对象的HashCode和 equals方法。

提示
(1)通常情况,自己编程时要做到:一个类的两个实例对象用equals方法比较的结果相等时,他们的哈希吗也必须相等,但反之则不成立,即equals方法比较的结果不相等的对象可以有相等的哈希吗或者说哈希吗相等的两个对象的equals方法的比较的结果可以不相等。因为默认的equals方法比较的是hashcoad值。例如,字符串”BB”和”Aa”的hashCode的结果相等,但equals的结果不相等。

(2)当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段,否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前的引用作为参数区HsahSet集合中检索对象,也将返回找不到对象的结果,这也是导致无法从HashSet集合中单独删除当前对象,从而造成内存泄露。



有关HashCode面试问题
hashcode把集合分为若干值域,把将要存入的数据转化为HashCode值后放入不同的区域,
当对象被存储进HashCode集合中以后,就不能修改这个对象中的那些参与计算哈希值得字段了,否则,对象修改后的哈希值与最近存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在contains 方法使用该对象当前的引用作为参数去HashSet集合检索对象,也将返回找不到对象的结果,这也会导致无法从HashSet集合中单独删除当前对象,从而造成内存泄露。



hashCode方法与HashSet类


如果想查找一个集合中是否包含有某个对象,大概的程序代码怎样写呢?当发现某个元素与要查找的对对象进行equals方法比较的结果相等时,则停止继续查找并返回肯定的信息,否则返回否定的信息。如果是一个集合中有很多元素,譬如有一万个元素,并且没有包含要查找的对象时,则意味着你的程序需要从该集合中取出一万个元素进行啄一的比较才能得到结论,有人发明了一种hashCode算法,来提高查找的效率,这种方式将集合分成若干个存储区域,每个对象可以计算出一个哈希码,可以将哈希码分组,每组分别对应某个存储区域,根据一个对象的哈希码就可以确定该对象应该存储在哪个区域,




hashSet就是采用哈希算法存储对象的集合,它内部采用对某个数字n进行取余的方式对哈希码进行分组的划分对象的存储区域。Object中的hashCode用来返回对就java对象的哈希码,从而提高查找的效率。



为了保证一个类的实例对象能在HashSet正常存储,要求这个类的两个实例对象用equals()方法比较的结果相等时,它们的哈希码也必须相等,也就是说,如果obj1.equals(obj2)的结果为true,那么一下表达式的结果页要为true。


obj1.hashCode() == obj2.hashCode()


如果一个类的hashCode()方法没有遵循上述要求,那么,当这个的两个实例对象用equals()方法比较的结果相等时,它们本来应该无法同时存储进Set集合中,但是,如果将它们存储进HashSet集合中时,由于它们的hashCode()方法的返回值不同,第二个对象首先按哈希码计算可能会被放进与第一个对象不同的区域中,这样,它就不可能与第一个对象进行equals方法比较了,也就可能被存储进HashSet集合中了。Object类的hashCode()方法不能满足对象被存入到HashSet中的要求,因为它的返回值是通过对象的内存地址推算出来的,同一个对象在程序运行期间的任何时候返回的哈希值都是始终不变的,所以,只要是两个不同的实例对象,即使它们的equals方法比较结果相等,它们默认的hashCode方法的返回值是不同的。
提示:


(1)通常来说,一个类的两个实例对象用equals()方法比较的结果相等时,它们的哈希码也必须相等,但反之则不成立,即euqlas方法比较结果不相等的对象可以有相同的哈希码,或者说哈希码相同的两个对象的equals方法比较的结果可以不等,例如,字符串“BB”和"Aa"的euqals方法比较结果肯定不相等,但它们的hashCode方法返回值却相等。


(2)当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在cantains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回找不到对象的结果。这也会导致从HashSet集合中单独删除当前对象,从而造成内存泄露。


关于 内存泄漏:http://blog.csdn.net/elimago/article/details/1946380

分享到:
评论

相关推荐

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

    本篇将深入探讨ArrayList与HashSet的区别,并分析Hashcode在其中的作用。 ArrayList是基于动态数组实现的,它提供了按索引访问元素的能力,就像在数组中一样。由于内部维护了一个数组,ArrayList保证了元素的顺序性...

    Java高新技术Java高新技术.doc

    6. **ArrayList与HashSet的比较**:`ArrayList`是有序且可重复的,它按照元素插入的顺序存储数据。而`HashSet`是无序且不可重复的。在插入元素时,`HashSet`会检查元素的`hashCode`,以确定其存储位置,从而快速查找...

    java中Hashcode的作用.docx

    在Java中的散列表(如HashMap、HashSet等)中,Hashcode扮演着关键角色。它可以快速地判断两个对象是否相等,从而提高散列表的性能。 证明Hashcode不是内存地址 有人认为Hashcode是对象在内存中的地址,但这是一种...

    Java_api.rar_java API_java api

    3. **集合框架**:`java.util`包中的集合框架包括`List`、`Set`和`Map`接口,以及它们的实现类如`ArrayList`、`HashSet`、`HashMap`等。这些接口和类提供了存储和操作对象的高效方法。 4. **输入输出流**:`java.io...

    Java容器集合(equals 和 hashCode+基础数据结构+ArrayList+Vector和LinkedList)

    Java容器集合(equals和hashCode+基础数据结构+ArrayList+Vector和LinkedList) Java容器集合是Java中的一种基础数据结构,用于存储和管理数据。其中,equals和hashCode方法是Java容器集合中两个非常重要的方法,...

    JDK API.rar_API_java api_java se api_jdk_villagesoc

    2. **集合框架**:`java.util`包提供了集合相关的类,如`List`、`Set`和`Map`接口,以及它们的实现,如`ArrayList`、`LinkedList`、`HashSet`、`HashMap`等。集合框架使得数据的存储、操作和管理变得更加方便。 3. ...

    Java_api_6开发帮助文档中文网页版(java_api_6_zh_cn)

    2. **集合框架**:Java 6中的集合框架包括List、Set、Queue和Map等接口,以及ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap等实现类。它们提供了丰富的操作集合的方法,如add、remove、contains、get...

    Java_API_V63_manual.zip_JAVA API接口

    3. **集合框架**:从Java 5开始,集合框架得到了显著增强,包括接口如`List`、`Set`和`Map`,以及实现这些接口的类如`ArrayList`、`HashSet`、`HashMap`。集合框架使得数据存储和操作更为高效便捷。 4. **IO与NIO**...

    java_API.rar_Javaapi _java api学习

    例如,`java.lang.Object`是所有Java类的根类,它包含了一些基本的方法,如`equals()`、`hashCode()`和`toString()`。接口则是一种定义行为的抽象,它包含了一组抽象方法,比如`java.util.Comparator`接口用于比较...

    03_ListAndSet_java_order64n_源码

    总结一下,本主题主要探讨了Java中List(ArrayList和LinkedList)和Set(HashSet)的数据结构及其实现。通过源码分析,我们可以了解它们在存储、访问和修改元素时的效率差异,以及在处理大数据量时应考虑的问题。...

    关于Java_Collection_API_

    ### Java Collection API 关键知识点详解 #### 一、线程安全集合类 在Java的Collection框架中,集合类被划分为两大类:线程安全集合类与非线程安全集合类。早期版本的集合类(如`Vector`和`Hashtable`)通过`...

    学习笔记 java\CoreJava笔记\CoreJava_day11

    5. **Vector类**:Vector与ArrayList类似,也是基于数组实现的列表,但它继承自AbstractList并实现了Serializable、Cloneable接口。不同之处在于,Vector是线程安全的,因此在多线程环境中可以直接使用,但这也意味...

    Java_API_1.8_zh_中文版.zip

    ArrayList和LinkedList是两种常见的List实现,HashSet和TreeSet是Set的代表,HashMap和TreeMap则属于Map。 3. **多线程**:Java提供了Thread类来支持并发编程,允许同时执行多个任务。此外,Runnable接口也是创建...

    java后端面试题答案_pdf

    Java 后端开发是软件行业中一个重要的领域,其面试题涵盖了广泛的编程概念和技术。这份PDF文档显然为准备Java后端面试的候选人提供了丰富的学习资源。以下是对标题和描述中涉及的一些核心知识点的详细解释: 1. **...

    JAVA_JDK_API_1_6_zh_CN文档.zip

    2. **集合框架**:Java 6引入了完善的集合框架,包括`List`、`Set`、`Map`接口和它们的各种实现类,如`ArrayList`、`LinkedList`、`HashSet`、`HashMap`等。这些接口和类提供了存储和操作对象的高效方式。 3. **...

    HashSet类的用法.pdf

    - 当`HashSet`中的元素为自定义类型时,必须正确地重写`equals()`和`hashCode()`方法以确保元素的唯一性和性能。 以上是对`HashSet`类的基本用法及特性的一个详细介绍。希望这些内容能帮助读者更好地理解和使用`...

    1-Collections-Overview-Section-Java-Collections-S_overview

    - 哈希表:HashMap和HashSet的底层数据结构,通过对象的hashCode快速定位元素,解决冲突通常采用链地址法。 - 红黑树:TreeMap和TreeSet的实现,保证O(logn)的时间复杂度进行插入、删除和查找操作。 7. 链表和...

    Java-API-chinese_help.zip_Help!

    Java API中文版帮助文档是Java开发者的重要参考资料,它包含了Java平台标准版(Java SE)的所有公共类、接口和方法的详细信息。这份文档通常以CHM(Microsoft Compiled HTML Help)格式提供,便于用户离线查阅。下面...

    Java Collections集合继承结构_动力节点Java学院整理

    `HashSet`通过`hashCode()`和`equals()`方法确保元素唯一性,基于哈希表实现,线程不安全。`TreeSet`则是一个有序的集合,通过`compareTo()`或`compare()`方法保证元素唯一性,其内部结构为二叉树,可以对集合元素...

    [Java参考文档].JDK_API_1_6_zh_CN

    2. **集合框架**:这是Java处理数据集合的重要工具,包括List、Set、Map等接口,以及ArrayList、LinkedList、HashSet、HashMap等实现类。集合框架使得开发者能够高效地组织和操作数据。 3. **IO流**:Java的IO流...

Global site tag (gtag.js) - Google Analytics