HashSet不可重复的原理

在Java基础重修的知识整理中 我会把知识点尽可能的方法代码中 以注释的形式提体现 所有代码都是全部 不是片段 若碰到和我一样的朋友伙伴 也可以复制代码运行 思考 通过注释都能做到底层源码的知其然知其所以然。

package cn.itcast.day12.demo02;

/**
 * @author admin
 * @version 1.0.0
 * @ClassName Demo06.java
 * @Description TODO
 * @createTime 2021年09月24日 20:07:00
 */

import java.util.HashSet;

/**
 * HashSet存储自定义类型元素
 * set集合保证元素唯一
 * 
 * 存储的元素(String Interger ..Student...Person )只要存储自定义类型的数据 必须重写hashcode和equals方法
 * 
 * 要求:
 * 同名同年龄得人 视为同一个人 只能存储一次
 */
public class Demo06 {
    public static void main(String[] args) {
        HashSet<Student> set = new HashSet<>();
        System.out.println("set = " + set);//set = []
        Student s1 = new Student("zhangsan", 23);
        Student s2 = new Student("lisi", 23);
        Student s3 = new Student("lisi", 23);


        /**
         * 哈希值相同 equals返回true 认定这两个元素是同一个元素 所以在set集合里面 我只会存储一次 这是set集合不可重复的原理重点
         */
        System.out.println("s2 = " + s2.hashCode());//02983077
        System.out.println("s3 = " + s3.hashCode());//02983077

        /**
         * ==和equals的区别
         *
         * 如果没有重写equals()方法,==和equals是相同的,因为在Object中equals方法就是通过==来实现的。
         *
         * 如果重写了equals方法,会按照我们重新写的比较逻辑来比较是否相同。
         * String重写了equals方法,所以str1.equals(str2)比较的是值。
         *
         */

        /*
        没有重写hashcode和equals方法的打印结果
         */
        System.out.println(s2 == s3);//false
        System.out.println(s2.equals(s3));//false

        /*
         重写hashcode和equals方法的打印结果
         */
        System.out.println(s2 == s3);//false 比较的是地址值
        System.out.println(s2.equals(s3));//trueb 比较的是值

        set.add(s1);
        set.add(s2);
        set.add(s3);
        /**
         *
         * 没有重写hashcode和equals方法
         */
        System.out.println("set = " + set);//set = [Student{name='lisi', age=23}, Student{name='lisi', age=23}, Student{name='zhangsan', age=23}]
        /**
         * 重写hashcode和equals方法
         */
        System.out.println("set = " + set);// set = [Student{name='lisi', age=23}, Student{name='zhangsan', age=23}]
    }

}

Student类

package cn.itcast.day12.demo02;

import java.util.Objects;

/**
 * @author admin
 * @version 1.0.0
 * @ClassName Student.java
 * @Description TODO
 * @createTime 2021年09月24日 20:21:00
 */

public class Student /*extends Object*/ {
    /**
     * 属性
     */
    private String name;
    private int age;

    /**
     * 重写hashcode 和equals方法
     */

    @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 &&
                Objects.equals(name, student.name);
    }

    /**
     * 无参方法
     */
    public Student() {
    }

    /**
     * 有参方法
     */
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    /**
     * GetSet方法
     */

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    /**
     * toSring的源码
     * <p>
     * return getClass().getName() + "@" + Integer.toHexString(hashCode());
     * 调用的对象的tostring方法
     * 如果没有重写tostring那就是类名+16进制的hashcode值
     */
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Guess you like

Origin blog.csdn.net/nanyangnongye/article/details/120462785