关于HashCode和equals方法在HashSet中的使用

编程之家收集整理的这篇文章主要介绍了关于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是两个不同对象。

这里写图片描述

总结

以上是编程之家为你收集整理的关于HashCode和equals方法在HashSet中的使用全部内容,希望文章能够帮你解决关于HashCode和equals方法在HashSet中的使用所遇到的程序开发问题。

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您喜欢交流学习经验,点击链接加入编程之家官方QQ群:1065694478

猜你在找的Java相关文章

在开发过程中,我们有时需要将重要的错误日志通过邮件发送给相关的责任人,这样能即时发现错误,即时解决。如使用Log4J,一般会做如下配置: 但是我在使用过程中发现标准的 org.apache.log4j
大家都知道使用java反射可以在运行时动态改变对象的行为,甚至是private final的成员变量,但并不是所有情况下,都可以修改成员变量。今天就举几个小例子说明。 基本数据类型 String类型
模型设计 &amp;emsp;&amp;emsp;旅馆管理系统,主要涉及到登记入住,退房以及客房和客人信息管理;经过分析抽像出涉及到的实体以及各实体之间的关系: &amp;emsp;&amp;emsp
RPC,全称为Remote Procedure Call(远程过程调用)。通俗一点讲就是在本地调用远程服务器上的功能。实现远程调用至少需要满足以下几个条件: 1.网络通信 2.序列化与反序列化 3.反
背景 系统: SpringBoot开发的Web应用; ORM: JPA(Hibernate) 接口功能简述: 根据实体类ID到数据库中查询实体信息,然后使用RestTemplate调用外部系统接口获取
【目录】 &quot;1.前言&quot; &quot;2.初现端倪&quot; &quot;3.款款深入&quot; &quot;4.责任细分&quot; &quot;5.功能层级图&quot; &
在高性能硬件上部署程序,目前主要有两种方式: 1. 通过64位JDK来使用大内存。 2. 通过若干个32位虚拟机建立逻辑集群来利用硬件资源。 32位的虚拟机和64位的虚拟机部署应用有什么区别? 1.
1. 垃圾回收的简单回顾 关于垃圾回收算法,基本就是那么几种:标记-清除、标记-复制、标记-整理。在此基础上可以增加分代(新生代/老年代),每代采取不同的回收算法,以提高整体的分配和回收效率。 无论使
jps JVM Process Status Tool,显示指定系统内所有的 HotSpot 虚拟机进程。显示信息包括虚拟机执行主类名称以及这些进程的本地虚拟机唯一ID(Local Virtual M
BTrace 是什么? BTrace 是一个动态安全的 Java 追踪工具,它通过向运行中的 Java 程序植入字节码文件,来对运行中的 Java 程序热更新,方便的获取程序运行时的数据信息,并且,保
一、标记 清除算法(Mark Sweep) 这种算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。 Mark Sweep 算法是最基础的收集算法,
一、JVM 内存区域 堆 - Heap 线程共享,JVM中最大的一块内存,此内存的唯一目的就是存放对象实例,Java 堆是垃圾收集器管理的主要区域,因此很多时候也被称为“GC堆”(Garbage Co