• 关于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是两个不同对象。
    这里写图片描述

  • 相关阅读:
    Android开发常见问题及解决方法
    Jquery chosen动态设置值实例介绍 select Ajax动态加载数据 设置chosen和获取他们选中的值
    Unity3d 基于物理渲染Physically-Based Rendering之实现
    Unity3d 基于物理渲染Physically-Based Rendering之specular BRDF
    Unity3d HDR和Bloom效果(高动态范围图像和泛光)
    unity3d 制造自己的水体water effect(一)
    unity3d shader之Roberts,Sobel,Canny 三种边缘检测方法
    Unity3d shader之卡通着色Toon Shading
    NVIDIA CG语言 函数之所有数学类函数(Mathematical Functions)
    Unity3d 使用DX11的曲面细分
  • 原文地址:https://www.cnblogs.com/jzmanu/p/10284796.html
Copyright © 2020-2023  润新知