【Java基础题】HashSet是如何判断新增元素是否重复的?

HashSet通过元素的hashcode和equals方法判断新增元素是否重复。首先,根据对象的hashcode确定存储位置,如果哈希值相同,则使用equals方法进一步判断业务上的相等性。当equals返回true时,视为重复元素,否则可以添加到集合中。为避免哈希碰撞,需要正确重写hashcode和equals方法。
摘要由CSDN通过智能技术生成

HashSet是如何判断新增元素是否重复的? 

        首先我们要知道HashSet底层的数据结构是哈希表。根据哈希表得出的哈希值代表该对象的储存位置。

        HashSet先调用元素对象的hashcode方法,JVM虚拟机来判个对象在物理位置上是否相等,也就是看两个元素的哈希值是否相等,如果不等那肯定是不同对象,就直接添加进set集合。

        如果相等,再根据两个元素对象的equals方法判断在业务上是否相等,是否返回true,为ture则被认为是相同对象,不能重复添加,为false则可以添加。

拓展

常用类不用重写,先人已经写好了

自定义类(由于先人不知道这些类的比较规则,所以需要我们去重写)

(1)重写时,重写equals,也应该重写hashcode方法;

(2)在规范上,JVM要求:

  • equals方法返回true的两个对象,(两个对象重复了),hashcode也应该是同一个值(一个物理地址);
  • 而equals方法返回false的两个对象,hashcode也应该是不同的值;(两个对象没有重复,所以是两个不同的物理地址)

 建立一个StudentBean

public class StudentBean {
    private String name;
    private int grade;
    private int age;
}

 让hash算法根据内容计算hash 


    public int hashCode(){
         //每个对象的hashcode值是可以重写的。
        int code = 0;
        char[] nameArray = this.name.toCharArray();
        for(int i = 0; i < nameArray.length; i++){
            code += nameArray[i];
        }
        code += age+grade;
        return code;
    }

防止hash碰撞(地址值不一样,但hash值一样)的情况,重写equals,确保去除问题值

 @Override
    public boolean equals(Object obj) {//传进来一个stu对象
        if(obj ==null){ //对象不为非空
            return false;
        }
        if(this == obj){ //比较两个对象 (地址引用)
            return true;
        }
        if(obj instanceof StudentBean stu){ //同一个类型
            if(this.name.equals(stu.name) && this.age == stu.age
        && this.grade==grade){
                return true;
            }else{
                return false;
            }
        }else{
            return false;
        }
    }

   测试1

    public static void main(String[] args) {
      Set<StudentBean> stuSet = new HashSet<>();
      StudentBean stu1=  new StudentBean("江小白",18,1);
      StudentBean stu2=  new StudentBean("江小白",20,2);
        stuSet.add(stu1);
        stuSet.add(stu2);
    }

两个StudentBean对象,hash值不相等,不重复,两个都可以添加进Set集合 

 测试2

  public static void main(String[] args) {
      Set<StudentBean> stuSet = new HashSet<>();
      StudentBean stu3=  new StudentBean("江小白",18,2);
      StudentBean stu4=  new StudentBean("江小白",19,1);
        stuSet.add(stu3);
        stuSet.add(stu4);
    }

两个StudentBean对象,hash值 相等

继续equals判断,age和grade数据不等,返回false,两者不重复,都可以添加进Set集合

测试3

  public static void main(String[] args) {
      Set<StudentBean> stuSet = new HashSet<>();
      StudentBean stu5=  new StudentBean("江小白",18,1);
      StudentBean stu6=  new StudentBean("江小白",18,1);
        stuSet.add(stu5);
        stuSet.add(stu6);
    } 

两个StudentBean对象,hash值相等,且equals比较 返回true,两者重复,stu6无法添加进Set集合

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BroRiver

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值