在介绍java的集合时,我们提到,set是一个“罐子”。我们可以向其中放入各式各样的元素,这些元素没有顺序,但不能相同。其中,HashSet是最常用的一个实现类。

首先,我们看下HashSet的源码。

/**
* Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
* default initial capacity (16) and load factor (0.75).
*/
public HashSet() {
map = new HashMap<>();
}
 /**
     * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
     * the specified initial capacity and default load factor (0.75).
     *
     * @param      initialCapacity   the initial capacity of the hash table
     * @throws     IllegalArgumentException if the initial capacity is less
     *             than zero
     */
    public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }

可以看出,HashSet是基于HashMap实现的,用其来保存元素。保存时,由HashMap的key、value来实现。

回顾下集合的父接口Collection中提供的方法。

 // Comparison and hashing

boolean equals(Object o);

int hashCode();

HashMap集合判断两个元素相等的标准:两个对象的equals方法相等,并且hashCode方法返回值也相等。

下面通过几个例子看一下:

1、只重写equals方法

public class HashSetTest1 {

	//重写equals方法,返回true
public boolean equals(Object obj){
return true; } }

2、只重写hashCode方法

public class HashSetTest2 {

	//重写hashCode方法,返回1
public int hashCode(){
return 1; } }

3、重写hashCode、equals方法

public class HashSetTest3 {

	//重写hashCode方法,返回2
public int hashCode(){
return 2; }
//重写equals方法,返回true
public boolean equals(Object obj){
return true;
} }

测试类如下:

public static void main(String[] args) {
HashSet test1 = new HashSet();
// 添加HashSetTest1
test1.add(new HashSetTest1());
test1.add(new HashSetTest1());
System.out.println("test1中元素的个数:" + test1.size()); HashSet test2 = new HashSet();
// 添加HashSetTest2
test2.add(new HashSetTest2());
test2.add(new HashSetTest2());
System.out.println("test2中元素的个数:" + test2.size()); HashSet test3 = new HashSet();
// 添加HashSetTest3
test3.add(new HashSetTest3());
test3.add(new HashSetTest3());
System.out.println("test3中元素的个数:" + test3.size());
}

执行结果为:

思考:

1、 HashSet中只把两个HashSetTest3对象当成了一个对象,因为只有他俩符合上述的规则,即equals、hashCode方法都相等。

2、如果需要重写equals方法,那么也应该重写hashCode方法。如HashSetTest1。

通过hashCode的返回值,我们可以看到,他返回的是一个int类型的值。在运算中,我们根据该元素的hashCode值计算出该元素的存储位置,以便快速定位。

HashSet如何判定两个元素相同的更多相关文章

  1. HashSet中是如何判断元素是否重复的

    HashSet不能添加重复的元素,当调用add(Object)方法时候, 首先会调用Object的hashCode方法判hashCode是否已经存在,如不存在则直接插入元素: 如果已存在则调用Obje ...

  2. Set集合对象比较两个元素的方法

    Set集合对象比较两个元素的方法并不是根据“equals()”方法的返回值来比较.而是用“hashCode()”方法来进行判断.只要两个元素的“hashCode()”方法的返回值相同,就认为两个元素相 ...

  3. 输出有序数组的中两个元素差值为指定值diff的两个元素

    题目: 输出有序数组的中两个元素差值为指定值diff的两个元素. 思路: 这与输出两个元素的和的值为一定值类似,需要两个指针,不同的是:指针不是一左一右,而是一前一后. 如果差值等于diff,则返回: ...

  4. 给一已经排序数组A和x,求A中是否包含两个元素之和为x

    亲爱的大神老爷们,这是小渣第一次写blog,欢迎大家来喷(批评指正),算法渣因为面试中连这道题都不会写就自己琢磨了一下,也参考了网上大家的做法 解法一: 思路:从首尾向目的靠拢,因为已经排序,[假设存 ...

  5. Openjudge-计算概论(A)-找和为K的两个元素

    描述: 在一个长度为n(n < 1000)的整数序列中,判断是否存在某两个元素之和为k. 输入第一行输入序列的长度n和k,用空格分开.第二行输入序列中的n个整数,用空格分开.输出如果存在某两个元 ...

  6. margin叠加相邻两个元素的上下margin是叠加在一起

    <!doctype html><html><head><meta charset="utf-8"><title>无标题文 ...

  7. 交换数组中两个元素的位置,元素包括key和value 一维数组

    /*author: yangyu@sina.cndescription: 交换数组中两个元素的位置,元素包括key和value,具体用法见下面的例子*/$arr = array(11=>'a', ...

  8. 《算法导论》习题2.3-7 查找集合S中是否有两个元素和为X---Java实现

    代码如下: public class MergeSort { public static void sort(int [] A,int p, int r) { if(p<r) { int q = ...

  9. js改变数组的两个元素的位子,互换、置顶

    //js数组的元素上移和下移动 var fieldData=[ {name:'id',value:'ID'} , {name:'username',value:'用户名'} , {name:'emai ...

随机推荐

  1. c/c++ 表白小程序

    1.开发工具: vs  vc(任选一个) 2.准备材料 : a.一首音乐 (注意:音乐要求重命名为  “x”  ) b.20张图片(注意: 图片要求重命名为  “1”  "2"   ...

  2. 《瞿葩的数字游戏》T3-三角圣地(Lucas)

    题目背景 国王1带大家到了数字王国的中心:三角圣地. 题目描述 不是说三角形是最稳定的图形嘛,数字王国的中心便是由一个倒三角构成.这个倒三角的顶端有一排数字,分别是1~N.1~N可以交换位置.之后的每 ...

  3. 富文本编辑器 summernote.js

    1.引用js  可在 https://summernote.org/ 官网下载 ,并查看详细的API  引入:summernote.js 和 summernote-zh-CN.js 以及样式文件:su ...

  4. Apache Maven(五):插件

    Maven的插件分如下两种: build plugins:该插件在项目构建阶段执行,它们都在<build>标签中设置. reporting plugins : 该插件在网站生成期间执行,他 ...

  5. C#5.0异步编程 HttpClient IP代理验证原码

    //访问HttpClient 代码 public async Task<string> VerifyProxy(string url, string proxy = "" ...

  6. C# Regex正则验证规则

    using System; using System.Text.RegularExpressions; namespace MetarCommonSupport { /// <summary&g ...

  7. django的查询集

    查询集表示从数据库中获取的对象集合,在管理器上调用某些过滤器方法会返回查询集,查询集可以含有零个.一个或多个过滤器.过滤器基于所给的参数限制查询的结果,从Sql的角度,查询集和select语句等价,过 ...

  8. SQL语句笔记/好记性不如烂笔头/持续更新

    常用的增删改查操作,针对库,表,字段,记录分类有助于记忆,当然熟能生巧,还是需要多多实操 库操作 删除库 drop database dbx; 列出所有库 show databases; 切换库 us ...

  9. C# 面试题 (一)

    一.C# 理论 1.1.简述 private. protected. public. internal.protected internal 访问修饰符和访问权限 private : 私有成员, 在类 ...

  10. Python: 列表的两种遍历方法

    方法一:以列表中元素的下标进行访问 def traverse1(list1): for i in range(len(list1)): print(list1[i], end=' ') print() ...