热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

为自定义类实现hashcode和equals-Implementinghashcodeandequalsforcustomclasses

SoIhavemanycustomclassesarealsohavecustomclasesinsideofthemusingcomposition.所以我有很多自

So I have many custom classes are also have custom clases inside of them using composition.

所以我有很多自定义类,其中也有使用组合的自定义clases。

My custom classes have variables that change very frequently and I add them to HashSets. So my question is when I implement hashCode - what should I do for a class that only has private fields that constantly change?

我的自定义类具有非常频繁更改的变量,我将它们添加到HashSet。所以我的问题是当我实现hashCode时 - 对于只有私有字段不断变化的类,我该怎么做?

Here is an example of one custom class:

以下是一个自定义类的示例:

public class Cell {
    protected boolean isActive;
    protected boolean wasActive;

    public Cell() {
    this.isActive = false;
    this.wasActive = false;
    }

    // getter and setter methods...

    @Override
    public int hashCode() {
    // HOW SHOULD I IMPLEMENT THIS IF THIS custom object is constantly
        // being added into HashSets and have it's private fields isActive
        // and wasActive constantly changed.
    }

    // ANOTHER QUESTION Am I missing anything with this below equals implementation?
    @Override
    public boolean equals(Object object) {
    boolean result = false;
    if (object instanceof Cell) {
        Cell otherCell = (Cell) object;
        result = (this.isActive == otherCell.isActive && this.wasActive == 
            otherCell.wasActive);
    }
    return result;
    }

3 个解决方案

#1


3  

Equals and hashCode contract in Java:

We must override hashCode() when we override equals() method, equals method in Java must follow its contract with hashCode method in Java as stated below.

当我们重写equals()方法时,我们必须覆盖hashCode(),Java中的equals方法必须遵循其与Java中的hashCode方法的契约,如下所述。

  1. If two objects are equal by equals() method then there hashcode must be same.
  2. 如果两个对象等于equals()方法,则哈希码必须相同。
  3. If two objects are not equal by equals() method then there hashcode could be same or different.
  4. 如果两个对象不等于equals()方法,则哈希码可以相同或不同。

These are sample implementation of equals and hashcode methods for your class:

这些是您的类的equals和hashcode方法的示例实现:

 //Hashcode Implementation    

   @Override
    public int hashCode() 
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + (isActive ? 1231 : 1237);
        result = prime * result + (wasActive ? 1231 : 1237);
        return result;
    }

//equals Implementation    
    @Override
    public boolean equals(Object obj) 
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Cell other = (Cell) obj;
        if (isActive != other.isActive)
            return false;
        if (wasActive != other.wasActive)
            return false;
        return true;
    }

#2


1  

You are SOL. Where hashCode() is used in a key in standard Java collections, it should not change. Or else you need a custom HashSet-like implementation.

你是SOL。在标准Java集合中的键中使用hashCode()的地方,它不应该更改。否则你需要一个类似HashSet的自定义实现。

Use only non-changing fields (or, if you are daring and don't mind occasional crashes, very rarely changing fields) to calculate hashCode().

仅使用不变的字段(或者,如果您大胆并且不介意偶尔崩溃,很少更改字段)来计算hashCode()。

(Added). In your particular example, use Object.hashCode().

(添加)。在您的特定示例中,使用Object.hashCode()。

(Added #2) Even if your Cell class were immutable (the two booleans didn't change) it makes a poor choice for hashing, because it only has 2 bits of range. Imagine hashing all people by whether they are male/female and blue eyes / brown eyes. A very good start, but there's only 4 categories, and there will be like 2 billion people in each one. Ideally, you'd have several other categories, like year of birth, country of birth, etc.

(添加#2)即使你的Cell类是不可变的(两个布尔值没有改变),它也很难选择散列,因为它只有2位的范围。想象一下,所有人都是男性/女性和蓝眼睛/棕色眼睛。一个非常好的开始,但只有4个类别,每个类别将有20亿人。理想情况下,您还有其他几个类别,如出生年份,出生国家等。

#3


1  

Here is the example of class which has private fields.

以下是具有私有字段的类的示例。

public class Test {

    private int num;
    private String data;

    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if ((obj == null) || (obj.getClass() != this.getClass()))
            return false;
        // object must be Test at this point
        Test test = (Test) obj;
        return num == test.num
                && (data == test.data || (data != null && data
                        .equals(test.data)));
    }

    public int hashCode() {
        int hash = 7;
        hash = 31 * hash + num;
        hash = 31 * hash + (null == data ? 0 : data.hashCode());
        return hash;
    }

}

推荐阅读
  • 本文介绍如何使用 Android 的 Canvas 和 View 组件创建一个简单的绘图板应用程序,支持触摸绘画和保存图片功能。 ... [详细]
  • 实体映射最强工具类:MapStruct真香 ... [详细]
  • 深入解析Java枚举及其高级特性
    本文详细介绍了Java枚举的概念、语法、使用规则和应用场景,并探讨了其在实际编程中的高级应用。所有相关内容已收录于GitHub仓库[JavaLearningmanual](https://github.com/Ziphtracks/JavaLearningmanual),欢迎Star并持续关注。 ... [详细]
  • 深入解析Spring启动过程
    本文详细介绍了Spring框架的启动流程,帮助开发者理解其内部机制。通过具体示例和代码片段,解释了Bean定义、工厂类、读取器以及条件评估等关键概念,使读者能够更全面地掌握Spring的初始化过程。 ... [详细]
  • 在尝试使用C# Windows Forms客户端通过SignalR连接到ASP.NET服务器时,遇到了内部服务器错误(500)。本文将详细探讨问题的原因及解决方案。 ... [详细]
  • 本文详细探讨了JDBC(Java数据库连接)的内部机制,重点分析其作为服务提供者接口(SPI)框架的应用。通过类图和代码示例,展示了JDBC如何注册驱动程序、建立数据库连接以及执行SQL查询的过程。 ... [详细]
  • 本文探讨了在Java中实现系统托盘最小化的两种方法:使用SWT库和JDK6自带的功能。通过这两种方式,开发者可以创建跨平台的应用程序,使窗口能够最小化到系统托盘,并提供丰富的交互功能。 ... [详细]
  • 本文介绍了Android开发中Intent的基本概念及其在不同Activity之间的数据传递方式,详细展示了如何通过Intent实现Activity间的跳转和数据传输。 ... [详细]
  • 本文详细介绍了 org.apache.commons.io.IOCase 类中的 checkCompareTo() 方法,通过多个代码示例展示其在不同场景下的使用方法。 ... [详细]
  • 本文探讨了使用C#在SQL Server和Access数据库中批量插入多条数据的性能差异。通过具体代码示例,详细分析了两种数据库的执行效率,并提供了优化建议。 ... [详细]
  • JavaScript 基础语法指南
    本文详细介绍了 JavaScript 的基础语法,包括变量、数据类型、运算符、语句和函数等内容,旨在为初学者提供全面的入门指导。 ... [详细]
  • 异常要理解Java异常处理是如何工作的,需要掌握一下三种异常类型:检查性异常:最具代表性的检查性异常是用户错误或问题引起的异常ÿ ... [详细]
  • 本文介绍如何使用MFC和ADO技术调用SQL Server中的存储过程,以查询指定小区在特定时间段内的通话统计数据。通过用户界面选择小区ID、开始时间和结束时间,系统将计算并展示小时级的通话量、拥塞率及半速率通话比例。 ... [详细]
  • 在 Android 开发中,通过 Intent 启动 Activity 或 Service 时,可以使用 putExtra 方法传递数据。接收方可以通过 getIntent().getExtras() 获取这些数据。本文将介绍如何使用 RoboGuice 框架简化这一过程,特别是 @InjectExtra 注解的使用。 ... [详细]
  • 深入解析动态代理模式:23种设计模式之三
    在设计模式中,动态代理模式是应用最为广泛的一种代理模式。它允许我们在运行时动态创建代理对象,并在调用方法时进行增强处理。本文将详细介绍动态代理的实现机制及其应用场景。 ... [详细]
author-avatar
手机用户2502922161
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有