Java——HashSet存储元素不重复的原理?以及如何保证存储对象内容也不重复?

package com.zzfl.other;

import java.util.HashSet;

/*
 *   实时(现场)代码模板(Live Templates)
 *   (1)psvm (2)sout (soutm、soutv、soutp、xxx.sout)
 *   (3)fori (iter、数组或集合.fori)(4)inn (ifn 、xxx.nn、xxx.null)
 *   (5)prsf:可生成 private static final
 *   类似的:
 *   psf:可生成 public static final psfi:可生成 public static final int
 *   psfs:可生成 public static final String
 *   快捷键
 *   ctrl+/ 单行注释    ctrl+shift+/ 多行注释   Ctrl+D 复制行   Ctrl+X 或 Ctrl+Y 删除行
 *   alt+enter 快速修正  alt+/ 代码补全  ctr+alt+L 格式化代码 ctr+shift+U 大小写转化
 *   Ctrl+Alt+O 优化导入的类和包 Alt+Insert 生成代码(如get,set方法,构造函数等)   Ctrl+P 方法参数提示
 *   Ctrl+H 显示类结构图   Ctrl+Q 显示注释文档   CTRL+ALT+M 抽取方法 Shift+Enter,向下插入新行  Ctrl+Alt+Enter 向上插一行
 *   Ctrl+Shift+Up/Down代码向上/下移动。double shift 按两次shift键 全局搜索
 *   CTRL+ALT+T 把选中的代码放在 try{} if{} else{}里  Ctrl+鼠标点击 查看源码
 *   Shift+F6 文件重命名或者是变量重命名  Ctrl+Shift+T 为当前类设置单元测试
 *   Ctrl+shift+Enter 在小括号、方括号、大括号等输入完成之后自动跳出括号并且带上“;”
 *   F8 单步跳过(step over); F7 单步进入(step  into) Alt+Shift+F7 强制单步进入(force step into)
 *   Shift+F8 单步退出(step out) F9 继续执行(resume program)
 *   面向对象的7大原则:
 *   1.开闭原则:面向扩展开放,面向修改关闭。
 */
class Student {

    String name;
    Integer age;
    String sex;
    Double score;
    public Student() {
    }

    public Student(String name, Integer age, String sex, Double score) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.score = score;
    }

    /*
    重写hashCode()方法,定义内容相同的哈希码相同,内容不同的哈希码不同
     */
    @Override
    public int hashCode() {
        return this.name.hashCode()+this.age+this.sex.hashCode()+this.score.hashCode();
    }
    //触发条件:两个对象的哈希码相同,才会触发equals()方法

    @Override
    public boolean equals(Object obj) {
        if (this==obj)
            return true;
        if (obj==null)
            return false;
        if (this.getClass()!=obj.getClass())
            return false;
        Student student = (Student)obj;

        if (this.name.equals(student.name) && this.age.equals(student.age) && this.score.equals(student.score )&& this.sex.equals(student.sex)) {
            return true;
        }
        return false;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                ", score=" + score +
                '}'+this.hashCode();
    }
}
public class TestHashSet2 {
    public static void main(String[] args) {
        Student s1 = new Student("安琪拉", 20, "女", 90.5);
        Student s2 = new Student("关羽", 45, "男", 86.5);
        Student s3 = new Student("貂蝉", 19, "女", 88.6);
        Student s4 = new Student("赵云", 25, "男", 99.6);
        Student s5 = new Student("赵云", 25, "男", 99.6);

        HashSet<Student> students=new HashSet<>();
        students.add(s1);
        students.add(s2);
        students.add(s3);
        students.add(s4);
        students.add(s1);//插入重复对象(地址重复)
        /*
        地址不同,内容相同情况下还是会插入hashset集合当中,因为s4和s5
        返回的哈希码是不同的,因此是不会除法equals进行二次比较的,此时就需要
        重写hashCode()方法,来保证内容相同的返回相同哈希码,内容不同的
        返回不同的哈希码。
         */
        students.add(s5);//插入重复对象(地址不同内容相同)

        for (Student student : students) {
            System.out.println(student);
        }

    }
}

 

HashSet保证元素不重复是通过两部分实现的,第一步通过比较两个对象的哈希码是否相同如果相同,只能怀疑是相同对象,那么进而就会调用equals就行二次确认,如果确认完毕之后相同,那么就会排除第二个,否则的话就会插入该元素。因此,如果要保证存入对象的内容不同的时候就需要同时重写hash()和equals()方法自己定义比较的规则,一定要保证相同内容的对象的哈希码是相同的,不同对象的哈希码是不同的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值