java中hashset集合equals重写问题

img


我重写的代码,当id重复的时候就添加失败,为啥没重复不输出那个添加成功?
对于hashcode的重写数返回了id的hashcode值

看你的代码怎么调用的。equals就是判断两个对象相等,为啥要加上什么添加成功添加失败这些不相干的逻辑。这些应该放在主程序

  • 这篇文章讲的很详细,请看:java中equals和hashCode方法为什么总是需要重写?
  • 除此之外, 这篇博客: Java 中重写了 equals 为什么还要重写 hashCode?中的 问题复现 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 先看如下代码,想一下 Set 集合中最终有几个元素。

    @Slf4j
    public class EqualsTest {
        public static void main(String[] args) {
            Teacher teacher1 = new Teacher("李四");
            Teacher teacher2 = new Teacher("李四");
            Teacher teacher3 = new Teacher("李四");
            Teacher teacher4 = new Teacher("李四");
            Set<Teacher> teachers = new HashSet<>();
            teachers.add(teacher1);
            teachers.add(teacher2);
            teachers.add(teacher3);
            teachers.add(teacher4);
            log.warn("集合大小: {}", teachers.size());
            teachers.forEach(System.out::println);
        }
    }
    

    在这里插入图片描述可以看到,HashSet 并没有去重,四个相同的对象,都保存进了 HashSet。这就是没有重写 hashCode 方法导致的结果。
    这里我先说结论:在 Java 中,当往哈希(散列)集合中添加元素时,先去判断 hashCode 值是否相同,如果不同,则直接插入。如果相同,才去判断 equals
    可以自己重写一个 hashCode 方法,比如写死返回 1。然后 equals 写死返回 false。然后在 add 方法,hashCode 方法,equals 方法上分别打上断点。那么此时集合中有四个 Teacher 对象。如果 equals 写死返回 true,则集合中只有一个对象。
    在这里插入图片描述
    在这里插入图片描述

  • 您还可以看一下 赵庆元老师的全栈工程师手把手带你学Java语言-高课程中的 重写equals和hashcode小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    根据参考资料和问题描述,可以发现问题出在重写的equals方法中,使用了id的hashCode值来判断是否重复,但是在id不重复时,没有成功添加元素。因此,需要修改代码才能成功添加元素。下面是具体的解决方案:

    1. 确认equals方法的实现是否正确,包括参数是否为Object类型,是否判断了null,是否判断了不同类型的对象等。
    2. 确认hashCode方法的实现是否正确,包括是否将id字段作为hashCode的计算基础,是否考虑到不同对象hashCode可能相同的情况。
    3. 对于不同对象hashCode相同的情况,需要在hashCode方法中添加其他属性字段,如name、age等,来确保生成的hashCode值唯一。
    4. 可以使用IDE工具自动生成hashCode和equals方法的实现,以确保正确性和完备性。同时也可以使用第三方库,如Apache Commons Lang的HashCodeBuilder和EqualsBuilder类来生成。
    5. 如果使用了自动生成的hashCode和equals方法,在修改后需要重新测试,确保逻辑正确,并将测试用例纳入自动化测试流程中。

    下面是一个可能的代码示例:

    public class Student {
        private int id;
        private String name;
    
        public Student(int id, String name) {
            this.id = id;
            this.name = name;
        }
    
        public int getId() {
            return id;
        }
    
        public String getName() {
            return name;
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(id, name);
        }
    
        @Override
        public boolean equals(Object obj) {
            if (obj == this) {
                return true;
            }
            if (!(obj instanceof Student)) {
                return false;
            }
            Student other = (Student) obj;
            return id == other.id && Objects.equals(name, other.name);
        }
    }
    

    在上面的代码中,使用了Objects类的静态方法hash()来计算hashCode值,使用了Objects类的静态方法equals()来比较两个对象是否相等,同时也考虑到了id和name两个属性字段的影响。可以根据实际情况修改代码并进行测试。