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

HashSet插入2个相等的元素

如何解决《HashSet插入2个相等的元素》经验,为你挑选了1个好方法。

我最近正在做一个涉及一套的基本任务,我偶然发现了一个奇怪的问题.我有以下课程:

public static class Quadruple {
    int a;
    int b;
    int c;
    int d;
    Map histogram;

    public Quadruple(int a, int b, int c, int d) {
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
        this.histogram = new HashMap<>();
        histogram.put(a, histogram.get(a) == null ? 1 : histogram.get(a) + 1);
        histogram.put(b, histogram.get(b) == null ? 1 : histogram.get(b) + 1);
        histogram.put(c, histogram.get(c) == null ? 1 : histogram.get(c) + 1);
        histogram.put(d, histogram.get(d) == null ? 1 : histogram.get(d) + 1);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof Quadruple)) {
            return false;
        }
        Quadruple q = (Quadruple) obj;
        return q.histogram.equals(this.histogram);
    }

    @Override
    public int hashCode() {
        return Objects.hash(a, b, c, d);
    }

当我初始化这种类型的2个对象时:

Quadruple q1 = new Quadruple(1, 1, 1, 2);
Quadruple q2 = new Quadruple(1, 1, 2, 1);

q1.equals(q2)返回true,但两个对象可以单独添加到HashSet.现在我从HashSet的契约中理解,如果你试图添加的对象是equals()一个已经存在的对象,那么它应该被认为存在并且不应该做任何事情.我设法通过使用LinkedList并在添加它之前检查列表是否包含()对象来避免这个问题,这似乎相应地起作用.

我的问题是,这种行为是否正常,因为我检查了底层实现,并发现HashSet中使用的HashMap实际上使用equals()检查值.有什么我可能会失踪?



1> Jaroslaw Paw..:

您的equals方法会进行比较histogram,但您会hashCode计算来自其他4个字段的哈希值.你的hashCode方法实现违反了equals和之间的契约hashCode,它说如果两个对象相等,它们必须具有相同的哈希值.

如果你看一下你的实现,Objects.hash你会得到这段代码:

public static int hashCode(Object a[]) {
    if (a == null)
        return 0;

    int result = 1;

    for (Object element : a)
        result = 31 * result + (element == null ? 0 : element.hashCode());

    return result;
}

正如你在循环中看到的那样,参数的顺序传递给了Object.hash问题.

至于解决方案,我真的没有理由拥有除了以外的领域histogram.无论哪种方式,给定equals方法的实现,您的hashCode方法应如下所示:

@Override
public int hashCode() {
    return histogram.hashCode();
}


推荐阅读
  • 使用Maven JAR插件将单个或多个文件及其依赖项合并为一个可引用的JAR包
    本文介绍了如何利用Maven中的maven-assembly-plugin插件将单个或多个Java文件及其依赖项打包成一个可引用的JAR文件。首先,需要创建一个新的Maven项目,并将待打包的Java文件复制到该项目中。通过配置maven-assembly-plugin,可以实现将所有文件及其依赖项合并为一个独立的JAR包,方便在其他项目中引用和使用。此外,该方法还支持自定义装配描述符,以满足不同场景下的需求。 ... [详细]
  • java解析json转Map前段时间在做json报文处理的时候,写了一个针对不同格式json转map的处理工具方法,总结记录如下:1、单节点单层级、单节点多层级json转mapim ... [详细]
  • 一、equals方法的作用1、默认情况(没有覆盖equals方法)下equals方法都是调用Object类的equals方法,而Objec ... [详细]
  • 案例packagecn.itcast_02;importjava.util.HashSet;**需求:存储自定义对象,并保证元素的唯一性* ... [详细]
  • 我正在尝试使用带有自定义类和哈希码方法的自定义类的哈希映射进行测试:publi ... [详细]
  • 转载请注明出处:http:blog.csdn.netsupera_liarticledetails45034203Effectivejava系列1.Effectivejav ... [详细]
  • 还要谈谈Equals和GetHashcode
    这篇随笔和上篇随笔《从两个数组中查找相同的数字谈Hashtable》都是为了下面分析Dictionary的实现做的铺垫一.两个逻辑上相等的实例对象。两个对象相等,除了指两个不同变量引用了 ... [详细]
  • Whenoverridingtheequals()functionofjava.lang.Object,thejavadocssuggestthat,当重写java.lang. ... [详细]
  • 1.何时需要重写equals()当一个类有自己特有的“逻辑相等”概念(不同于对象身份的概念)。2.为什么改写equals()的时候,总是要改写hashCode()两个原则:hashCode()的返回& ... [详细]
  • -------------------------------------------------android培训、java培训期待与您交流!--------------------------- ... [详细]
  • 在iOS开发中,多线程技术的应用非常广泛,能够高效地执行多个调度任务。本文将重点介绍GCD(Grand Central Dispatch)在多线程开发中的应用,包括其函数和队列的实现细节。 ... [详细]
  • 2020年9月15日,Oracle正式发布了最新的JDK 15版本。本次更新带来了许多新特性,包括隐藏类、EdDSA签名算法、模式匹配、记录类、封闭类和文本块等。 ... [详细]
  • 本文总结了Java初学者需要掌握的六大核心知识点,帮助你更好地理解和应用Java编程。无论你是刚刚入门还是希望巩固基础,这些知识点都是必不可少的。 ... [详细]
  • DAO(Data Access Object)模式是一种用于抽象和封装所有对数据库或其他持久化机制访问的方法,它通过提供一个统一的接口来隐藏底层数据访问的复杂性。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
author-avatar
Tony_Friday
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有