zoukankan      html  css  js  c++  java
  • 关于HashCode和equals方法在HashSet中的使用

    Object类是类层次结构的根类,故所有的类都是先该类的方法,其中HashCode()和equals()方法也是该类的方法。
    1.HashCode()方法
    Object类中HashCode()方法实现如下:

    public  native  int  hashCode();

    返回:该对象的哈希值,可提高哈希表的性能。
    HashCode:
    1.同一对象多次调用HashCode()方法,返回一直的整数,从某一程序的依次执行到同一程序的另一次执行,该整数无需保持一致;
    2.使用equals(Object)方法两个对象是相等的,那么两个对象返回的Hash值完全一致;
    3. 使用equals(Object)方法两个对象不相等,其返回的Hash值有可能相等。
    下面摘录API中String的HashCode()方法及相关属性:

    private final char value[];
        private int hash; // Default to 0
        public int hashCode() {
            int h = hash;
            if (h == 0 && value.length > 0) {
                char val[] = value;
    
                for (int i = 0; i < value.length; i++) {
                    h = 31 * h + val[i];
                }
                hash = h;
            }
            return h;
        }

    给定一个字符串,相当于在执行构造方法:

    public String() {
            this.value = new char[0];
    }

    此时,value值已经给定,此构造方法下value.length=0,显然hash=h=0(默认值为0,也就是空字符串),重在理解过程,哈希算法看API文档就好。

    String s = new String();
    System.out.Println(s.HashCode());
    结果:0

    2.equals()方法
    Object类中equals()方法的实现如下:

    public boolean equals(Object obj) {
            return (this == obj);
        }

    指示其他某个对象是否与此对象参数相同,相同返回true,反之。equals()方法在非空对象引用(obj)上实现相等关系,对于任何非空引用值x,x.equals(null)都应返回false。String等类都会覆盖Object类中的方法。
    3.类HashSet
    HashSet是Set接口的一个实现类,不能重复添加对象值,这个过程主要由Hash值和对象的equals()方法判断,使用add()方法添加某种类型对象
    //测试类

    package com.test;
    //测试类,该类重写了从Object继承而来的HashCode()和equals()方法
    public class StudentTest {
        private String name;
        private int age;
        public StudentTest(){}
        public StudentTest(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;
        }
    }

    //HashSet类

    package com.test;
    
    import java.util.HashSet;
    import java.util.Set;
    
    public class SetDemo {
        public static void main(String[] args) {
            Set<StudentTest> set1 = new HashSet<>();
            StudentTest s1 = new StudentTest("manu",10);
            StudentTest s2 = new StudentTest("manu",10);
    //      set1.add(null);//此处null元素可以使用
            set1.add(s1);
            System.out.println(s1.hashCode());
            set1.add(s2);
            System.out.println(s2.hashCode());
            System.out.println(set1.size());    
        }
    }
    运行结果:
    794284386
    779325750
    2

    上面s1、s2是两个对象,每一次添加对象是hash值都不同,故该对象可以添加到HashSet中,其size=2,上面涉及到一个问题,某个对象的属性一致,如果不想将属性一致的对象再一次添加进去,则必须重写StudentTest类的HashCode()方法和equals()方法,经过重写两者hash相同,在用equals方法来验证,返回true,表示两个对象重复,反之。代码如下:

    @Override
        public int hashCode() {
            System.out.println("hashCode");//用于测试
            final int prime = 31;
            int result = 1;
            result = prime * result + age;
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            return result;
        }
        @Override
        public boolean equals(Object obj) {
            System.out.println("equals");//用于测试
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            StudentTest other = (StudentTest) obj;
            if (age != other.age)
                return false;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            return true;
        }

    此时运行结果如下:

    hashCode
    hashCode
    3345234
    hashCode
    equals
    hashCode
    3345234
    1

    两者不同的对象,属性值一致,但不能添加到HashSet中,注意需求的变化。
    在HashSet中添加元素时,若hash值不一致,则可以添加;若hash值一致,调用equals方法看对象是否相同,不同(false)则可以添加。注意equals判断,某两个对象不同,hash值可能相同,上述示例中hash值相同,但s1和s2是两个不同对象。
    这里写图片描述

  • 相关阅读:
    那些离不开的 Chrome 扩展插件
    Spring Boot 实战 —— 入门
    Maven 学习笔记
    Linux lvm 分区知识笔记
    Linux 双向 SSH 免密登录
    CentOS Yum 源搭建
    Ubuntu 系统学习
    iOS 测试三方 KIF 的那些事
    Swift 网络请求数据与解析
    iOS Plist 文件的 增 删 改
  • 原文地址:https://www.cnblogs.com/jzmanu/p/10284796.html
Copyright © 2011-2022 走看看