Java的HashSet类
如果要查找一个集合中是否包含了某个对象,那么就需要把这个对象和这个集合中的每个对象依次进行比较和判断,直到找到这个对象为止,或者把所有对象都比较一次为止(如果最后一个对象才是要查找的对象,或者集合中没有包含要查找的对象)。当集合中的对象数量较多时,效率就很低。为了提高效率,提出了Hash算法。Hash算法对每一个对象都计算出一个Hash码,根据Hash码把对象分配到某个存储区域中,比如一个集合包含了很多人,根据国籍,中国人是一个存储区域,美国人是一个存储区域,英国人是一个存储区域,......。这样如果要查找该集合是否包含了某个中国人,就到中国人的存储区域去比较就行了,这样大大提高了效率。
Java中实现了Hash的集合是HashSet。HashSet查找某个对象时,首先用hashCode()方法计算出这个对象的Hash码,然后再根据Hash码到相应的存储区域用equals()方法查找,从而提高了效率。由于是集合,所以同一个对象只能有一个。
hashSet的例子如下所示:
package my; import java.util.HashSet;
import java.util.Set; class Person{ // 性别
String sex;
// 姓名
String name;
// 身高
Double hei;
// 体重
Double wei; public Person(String n, String s, Double h, Double w){
this.name=n;
this.sex=s;
this.hei=h;
this.wei=w;
} public String toString(){
return "\n姓名:"+this.name+" 性别:"+this.sex+" 身高:"+this.hei+" 体重:"+this.wei;
} } public class myHS { private static Set<Person> mySet = new HashSet<Person>();
public static void main(String[] args) {
mySet.add(new Person("Tom","Male",170.0,70.0));
mySet.add(new Person("Peter","Male",175.0,70.0));
mySet.add(new Person("Kate","Female",168.0,60.0));
mySet.add(new Person("Alice","Female",161.0,55.0));
mySet.add(new Person("Jack","Male",190.0,95.0));
mySet.add(new Person("Jack","Male",190.0,95.0));
System.out.println(mySet);
} }
以上例子先定义了Person类,然后定义了一个HashSet,并加入了5个Person到该集合,其中1个人加入了两次,运行结果如下:

可见Jack是同一个人,却在集合中出现了两次,这是什么原因呢?这是因为,Person是Object的子类,而Object类的equals()方法是根据对象的内存地址来判断两个对象是否相等的,由于两次插入的Jack的内存地址肯定不相同,所以判断的结果是不相等,所以两次都插入了。于是,我们需要覆写equals()方法来判断两个对象是否是同一个对象。
// 覆写equals方法
public boolean equals (Object obj){
// 地址相等,则肯定是同一个对象
if(this==obj){
return true;
}
// 类型不同,则肯定不是同一类对象
if(!(obj instanceof Person)){
return false;
}
// 类型相同,向下转型
Person per=(Person) obj;
// 如果两个对象的姓名和性别相同,则是同一个人
if(this.name.equals(per.name)&&this.sex.equals(per.sex))
return true;
return false;
}
覆写equals()方法以后,运行结果如下:

可见Jack仍然被插入了两次,这是什么原因呢?这是因为Object的Hash码返回的是对象的Hash地址,而两个对象的Hash地址肯定是不相等的,所以6次插入的对象被存储在6个存储区域,equals()方法根本没有运行。于是,还需要覆写hashCode()方法,根据姓名来计算对象的Hash码。
// 覆写hashCode方法
public int hashCode(){
return this.name.hashCode();
}
运行结果如下:

可见,Jack只插入了一次,终于正确了。如果根据性别来计算对象的Hash码,结果也是正确的,Jack也只会被插入1次。但是,如果两个对象的性别不同,如下所示:
mySet.add(new Person("Jack","Male",190.0,95.0));
mySet.add(new Person("Jack","Female",190.0,95.0));
则两个对象都会被插入:

这是因为虽然两个对象的Hash码相同(不论是按照姓名,还是按照性别来计算,Hash码都是相同的),但是equals()方法判断这两个对象不相等,于是都插入了。
Java的HashSet类的更多相关文章
- JDK1.8源码(八)——java.util.HashSet 类
在上一篇博客,我们介绍了 Map 集合的一种典型实现 HashMap ,在 JDK1.8 中,HashMap 是由 数组+链表+红黑树构成,相对于早期版本的 JDK HashMap 实现,新增了红黑树 ...
- Java API —— Set接口 & HashSet类 & LinkedHashSet类
1.Set接口 1)Set接口概述 一个不包含重复元素的 collection,无序(存储顺序和取出顺序不一致),唯一. (List有序,即存储顺序和取出顺序一致,可重复) ...
- Java——(三)Collection之Set集合、HashSet类
------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.Set集合 Set集合不允许包含相同的元素,如果试图把两个相同的元素加入同一个Set集合中, ...
- Java集合概述、Set集合(HashSet类、LinkedHashSet类、TreeSet类、EnumSet类)
Java集合概述.Set集合(HashSet类.LinkedHashSet类.TreeSet类.EnumSet类) 1.Java集合概述1)数组可以保存多个对象,但数组长度不可变,一旦在初始化数组时指 ...
- java——HashSet类中的常见方法
package com.xt.set; import java.util.HashSet; import java.util.Iterator; import java.util.Set; publi ...
- Java 数据类型:集合接口Collection之Set接口HashSet类;LinkedHashSet;TreeSet 类
Collection 之 Set 实现类: HashSet TreeSet 特点: 无序. 元素不可重复. (如果试图添加一个已经有的元素到一个Set集合中,那么会添失败,add()方法返回false ...
- JAVA Collections工具类sort()排序方法
主要分析内容: 一.Collections工具类两种sort()方法 二.示例 一.Collections工具类两种sort()方法 格式一: public static <T extends ...
- Java集合---Array类源码解析
Java集合---Array类源码解析 ---转自:牛奶.不加糖 一.Arrays.sort()数组排序 Java Arrays中提供了对所有类型的排序.其中主要分为Prim ...
- 【Java基础】类和接口
Num1:使类和成员的可访问性最小化 要区别设计良好的模块与设计不好的模块,最重要的因素在于,这个模块对于外部的其他模块而言,是否隐藏其内部数据和其他实现细节.设计良好的模块会隐藏所有的实现细节,把它 ...
随机推荐
- Robotium的左右为难 -- enterText
最近测试框架收到反馈,详查后发现了一个Robotium的问题,甚有趣,遂记录. 问题场景: Robotium.enterText输入数据后,点击"发送"按钮,多数情况下失败,少数时 ...
- redis系列-主从复制
redis自身提供了主从的机制,通过配置可以实现服务的备份(Master->Slave). 配置项 slaveof <masterip> <masterport> mas ...
- node.js1
node的helloworld是非常的简单. 下载node绿色安装包即可.转至node.exe所在目录——写一个hw.js,然后cmd下执行node hw.js——返回相应结果.. http://ww ...
- iOS 打包iPa
http://blog.fir.im/how-to-build-adhoc-ipa/ 之前都是打包好ipa然后发送给客户,特麻烦,fir.im网站不错 迅速获取自己手机的udid: http://f ...
- atitit opencv apiattilax总结 约500个函数 .xlsx
atitit opencv apiattilax总结 约500个函数 .xlsx 1.1. CxCore中文参考手册 1 1.2. 机器学习中文参考手册 knn svm 1 1.3. CvAu ...
- css_04之显示、定位
1.显示方式:display:取值:none(隐藏,不占页面空间,脱离文档流)/block(元素变为块级)/inline(元素变为行内)/inline-block(元素变为行内块): 2.显示效果:v ...
- cordovas禁止横屏
cordovas禁止横屏 官网 http://cordova.apache.org/docs/en/latest/config_ref/index.html#preference 配置config.x ...
- Linq 查询结果 可能遵循 2 º,2¹,2 ²,......增长计算
static void Main(string[] args) { , , , , , , , , }; var obj = from item in array orderby item ascen ...
- Java environment variables and their functionality
Explanations of Functionalities: 1. PATH env variable It is used to search the command directory whe ...
- 使用supervisor提高nodejs调试效率
如果你有PHP 开发经验,会习惯在修改PHP 脚本后直接刷新浏览器以观察结果,而你 在开发Node.js 实现的HTTP 应用时会发现,无论你修改了代码的哪一部份,都必须终止 Node.js 再重新运 ...