Java HashSet集合初探(一)

本文探讨了Java中的HashSet集合,强调其无序、不重复的特性。通过分析添加元素时调用hashCode()和equals()方法的过程,解释了如何确保元素不重复。示例展示了未重写这两个方法时可能出现的重复问题,以及重写后解决冲突的方法。最后,概述了HashSet的构造函数和常用方法,如add(), remove(), clear()等。" 87925127,8331219,链表详解与应用,"['数据结构', '链表操作', '内部类', '封装技巧', '递归算法']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
* @author StormWangxhu
* @version 创建时间:2017年11月4日 下午4:03:26
*
*/

Set集合

先来看看集合框架图:
这里写图片描述

  • 与List接口相同点:
    同样继承自Collection接口,它与Collection接口中的方法基本一致,并没有对Collection接口进行功能上的增强,但比Collection接口更加严格!
  • 不同点
    Set接口中的元素 无序、不重复! 至于以什么样的方式保证不重复,其原因后面会说到。

先来结合代码看看HashSet集合中添加重复元素会发生什么:

package com.stormwang.SetTest;

import java.util.HashSet;
import java.util.Iterator;

/**
* @author StormWangxhu
* @version 创建时间:2017年11月4日 下午4:03:26
*
*/
public class HashSetDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        HashSet set= new HashSet();
        //向集合中添加元素
        set.add("java");
        set.add("Friday");
        set.add("java");
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            Object object = (Object) iterator.next();
            System.out.println(object);
        }   
    }
}

再来看看结果:
这里写图片描述

在代码中,重复了字符串Java,但是运行后,只保留下了一个。
且可以看出,取出顺序和加入顺序也不一致。

原因:

不重复是因为做了很多工作:当向Set集合中添加对象时,add().
步骤:
1、首先调用当前存入对象的hashCode()方法,获得该对象哈希值。
2、根据哈希值确定其存储位置。
3、判断该位置上是否有对象

(1)、无对象,则存入集合。
(2)、有对象 ———->>>调用equal()方法,比较对象是否相等。
(3)、
相等——->>>舍弃该对象
不相等——存入该集合。

下面根据图来理解一下:
这里写图片描述

则要想HashSet正常工作,就必须重写hashCode()方法、equals()方法。

下面以没有重写两个方法演示一下后果:

package com.stormwang.SetTest;
/**
* @author StormWangxhu
* @version 创建时间:2017年11月4日 下午4:35:50
*
*/

import java.util.HashSet;
import java.util.Iterator;

/**
 * 不复写hashCode()方法、equals()方法
 * */
public class HashDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //创建集合
        HashSet set =new HashSet<>();
        //创建Student对象
        Student student = new Student("1", "Jack");
        Student student2 = new Student("2", "mary");
        Student student3 = new Student("3", "Rose");
        Student student4 = new Student("3", "Rose");
        set.add(student);
        set.add(student2);
        set.add(student3);
        set.add(student4);
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            Object object = (Object) iterator.next();
            System.out.println(object);
        }

    }

}
class Student{
    private String id ;
    private String name ;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    //构造方法
    public Student(String id,String name ) {
        this.id = id;
        this.name = name ;
    }
    //
    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + "]";
    }
}

看一下运行后效果:
这里写图片描述

看到: 出现了相同的值: [ id=3,name=Rose].

原因分析

是因为在类没有重写hashCode()方法,和equals()方法。这样的重复在HashSet集合中理应是不存在的。那么就重写这两个方法试试。
假设id相同的学生是一同一个学生。
看代码:

package com.stormwang.SetTest;
/**
* @author StormWangxhu
* @version 创建时间:2017年11月4日 下午4:35:50
*
*/

import java.util.HashSet;
import java.util.Iterator;

/**
 * 不复写hashCode()方法、equals()方法
 * */
public class HashDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //创建集合
        HashSet set =new HashSet<>();
        //创建Student对象
        Student student = new Student("1", "Jack");
        Student student2 = new Student("2", "mary");
        Student student3 = new Student("3", "Rose");
        Student student4 = new Student("3", "Rose");
        set.add(student);
        set.add(student2);
        set.add(student3);
        set.add(student4);
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            Object object = (Object) iterator.next();
            System.out.println(object);
        }

    }

}
class Student{
    private String id ;
    private String name ;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    //构造方法
    public Student(String id,String name ) {
        this.id = id;
        this.name = name ;
    }
    //
    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + "]";
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }








}

再来看看运行结果:

这里写图片描述

重复的没有了,保证了元素的不重复性。也会看到元素的无序性。

再看看HashSet的API

构造函数:
这里写图片描述

方法:

这里写图片描述

HashSet的一些常用方法

添加元素
hashset.add(E e):返回boolean型,如果此 set 中尚未包含指定元素,则添加指定元素;如果此 set 已包含该元素,则该调用不更改 set 并返回 false。

删除元素:
hashset.clear():从此 set 中移除所有元素。
hashset.remove(Object o):如果指定元素存在于此 set 中,则将其移除。
hashset.isEmpty():如果此 set 不包含任何元素,则返回 true。
hashset.contains(Object o):如果此 set 包含指定元素,则返回 true。
hashset.size():返回此 set 中的元素的数量(set 的容量)。

总结:

要想HashSet正常工作,必须重写hashCode()方法和equals()方法。

重写技巧:

右击——–>>source———->>Generate hashCode() and equals()….

就看到这儿吧,晚上再来一个实例练习HashSet()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值