HashSet如何检查重复

HashSet如何检查重复

当把对象加入HashSet时,HashSet会先计算对象的hashcode值来判断对象加入的位置,同时也会与其他加入的对象的hashcode值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同hashcode值的对象,这时会调用equals()方法来检查hashcode相等的对象是否真的相同。如果两者相同,HashSet就不会让加入操作成功。

咱们举个String类的例子,因为 String类重写了equals(),和hashCode()。

package com.cc;

import java.util.HashSet;

public class HashSetTest {
    public static void main(String[] args) {
        String str1 = new String("hello");
        String str2 = new String("hello");

        HashSet hashSet = new HashSet();

        hashSet.add(str1);
        hashSet.add(str2);

        System.out.println(hashSet.size());

        System.out.println(str1.hashCode());
        System.out.println(str2.hashCode());

        System.out.println(hashSet);
    }
}

运行结果:
在这里插入图片描述

可以看到两个字符串相等,hashCode相同。最终hashSet中只加入了一个元素。

hashCode()与equals()的相关规定:

  1. 如果两个对象相等,则hashcode一定也是相同的
  2. 两个对象相等,对两个equals方法返回true
  3. 两个对象有相同的hashcode值,它们也不一定是相等的
  4. 综上,equals方法被覆盖过,则hashCode方法也必须被覆盖
  5. hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写hashCode(),则该class的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)。

那咱们自己再来看一个Student例子,没重写equals(),和hashCode()。

package com.cc;

import java.util.HashSet;

public class HashSetTest {
    public static void main(String[] args) {
        Student student1 = new Student("moon",2);
        Student student2 = new Student("moon",2);

        HashSet hashSet = new HashSet();

        hashSet.add(student1);
        hashSet.add(student2);

        System.out.println(hashSet.size());

        System.out.println(student1.hashCode());
        System.out.println(student2.hashCode());

        System.out.println(hashSet);
    }
}

运行结果:
在这里插入图片描述

两个对象的hashCode不同,但是这两个对象是不是完全一样的,可就出现了问题。不符合hashCode()与equals()的规定。

那么你在Student类中重写equals(),和hashCode()这两个方法即可。

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Student student = (Student) o;
    return age == student.age &&
            name.equals(student.name);
}

@Override
public int hashCode() {
    return Objects.hash(name, age);
}

再次运行,发现只插入了一个对象。
在这里插入图片描述

发布了302 篇原创文章 · 获赞 23 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/hello_cmy/article/details/105296683
今日推荐