HashSet-哈希值

哈希值(哈希码值)?
    是JDK根据对象地址, 或者属性值, 计算出来的int类型的值
    
Object类中有一个方法可以获取对象的哈希值
    public int hashCode(); 根据对象地址计算哈希值并返回
    
对象哈希值的特点?
    1. 如果我们没有重写hashCode(), 那么根据对象的"地址值"计算哈希值
        同一个对象多次调用hashCode()获取的哈希值是一样的, 因为地址一样
        不同对象的哈希值是不一样的, 因为地址不一样
    2. 如果我们重写了hashCode(), 那么根据对象的"属性值"计算哈希值
        和对象地址就无关了!
        可能出现不同地址的对象, 但是哈希值一样, 原因是属性可能会一样

代码示例
//测试类
public class Demo {
    public static void main(String[] args) {
        //创建对象
        Student s1 = new Student("张三", 18);
        Student s2 = new Student("李四", 28);

        //打印s1哈希值
        System.out.println(s1.hashCode()); //根据地址2129789493 / 根据属性24021577
        System.out.println(s1.hashCode()); //根据地址2129789493 / 根据属性24021577
        //打印s2哈希值
        System.out.println(s2.hashCode()); //根据地址668386784 / 根据属性26103919
        //创建s3和s1属性相同,但是地址不同,打印s3哈希值
        Student s3 = new Student("张三", 18);
        System.out.println(s3.hashCode()); //根据属性24021577
    }
}
//学生类
class Student {
    @Override
    public int hashCode() {
        /*
            注意: 如果我们重写了hashCode(), 那么根据对象的"属性值"计算哈希值
                和对象地址就无关了!
         */
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }
    ...
}

 

11. HashSet

需求: 创建HashSet集合存储学生对象并遍历, 如果学生对象的成员变量相同, 认为是同一个对象不存

重点: 重写Student类的hashCode和equals方法即可

需求: 创建HashSet集合存储学生对象并遍历, 如果学生对象的成员变量相同, 认为是同一个对象不存

重点: 重写Student类的hashCode和equals方法即可

代码示例
    public class Demo {
        public static void main(String[] args) {
            //创建集合添加元素
            HashSet<Student> set = new HashSet<>();
            Student s1 = new Student("张飞",18);
            Student s2 = new Student("张飞",18);
            Student s3 = new Student("吕布",20);
            set.add(s1);
            set.add(s2);
            set.add(s3);
            //遍历集合
            for (Student stu : set) {
                System.out.println(stu);
                /*
                    打印结果
                        Student{name='张飞', age=18}
                        Student{name='张飞', age=18}
                        Student{name='吕布', age=20}

                    还是出现重复对象的原因
                        当前Student没有重写HashCode方法, 比较的是对象的地址值
                        s1和s2两个对象地址不同,所以计算出来的哈希值也不同!
                        重写Student类的hashCode和equals方法即可

                    重写后
                        Student{name='吕布', age=20}
                        Student{name='张飞', age=18}

                    结论
                        如果HashSet集合要存储自定义类的对象,那么该类必须重写hashCode和equals方法
                 */
            }
        }
    }

    class Student{
        // 重写Student类的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;

            if (age != student.age) return false;
            return name != null ? name.equals(student.name) : student.name == null;
        }

        @Override
        public int hashCode() {
            int result = name != null ? name.hashCode() : 0;
            result = 31 * result + age;
            return result;
        }
        ...
    }

12. HashSet-小结

         Set接口: 无序,无索引,不能重复
    HashSet实现类: 底层哈希表,如果存储自定义类,该类要重写hashCode和equals方法
    TreeSet实现类: 底层红黑树,可以排序,默认使用自然排序,也可以指定规则使用比较器排序

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值