【问题标题】:Check if HashSet/HashMap contains Object [closed]检查 HashSet/HashMap 是否包含对象 [关闭]
【发布时间】:2013-05-15 06:56:31
【问题描述】:

如果我想检查 MyClass 类的某个 Object 是否包含在 ArrayList 等中,我可以覆盖 equals。

public boolean equals(Object o) {
    .....
}

但是如果我想检查 MyClass 的对象是否包含在 HashMap 或 HashSet 中,我该怎么办? 我猜 hashCode 必须被覆盖?这是正确的吗?我该怎么做? 谢谢! 编辑:我完全了解 contains/containsKey 等。但是为什么覆盖列表而不是集合的等于就足够了。如果我只是测试一个数组列表是否包含一个对象,则覆盖的方法可以正常工作。对于 Set 来说,这还不够。我的问题是我还需要覆盖什么 i.o.去实现它。我不想要一个额外的方法,我猜关键在于 hashCode。

【问题讨论】:

标签: java hash hashmap hashset


【解决方案1】:

在任何情况下,如果您覆盖 equals,您应该始终覆盖 hashCode。

http://www.xyzws.com/javafaq/why-always-override-hashcode-if-overriding-equals/20

【讨论】:

  • 谢谢!这就是我一直在寻找的......
  • 那你应该把他的回答标记为接受。
  • 您必须等待 2 分钟才能执行此操作...
  • 啊,不知道。
【解决方案2】:

完全一样。其实有两部分

  • 在你的类中覆盖 equals 是有意义的

  • 使用容器中检索对象的方法。当然,那个方法会使用对象的equals方法。

HashSet 有一个contains() 方法和HashMap 一个containsKey/containsValue

【讨论】:

    【解决方案3】:

    是的,您必须在 MyClass 类中覆盖您的 equals() 方法。

    这是一个例子:

    public class MyClass {
        private String name;
        private String gender;
    
        public MyClass(String name, String gender) {
            this.name = name;
            this.gender = gender;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj) return true;
            if (obj == null) return false;
            if (getClass() != obj.getClass()) return false;
            MyClass other = (MyClass) obj;
            if (gender == null) {
                if (other.gender != null) return false;
            } else if (!gender.equals(other.gender)) return false;
            if (name == null) {
                if (other.name != null) return false;
            } else if (!name.equals(other.name)) return false;
            return true;
        }
    
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((gender == null) ? 0 : gender.hashCode());
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            return result;
        }
    
        public String getGender() {
            return gender;
        }
    
        public void setGender(String gender) {
            this.gender = gender;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    

    请注意,当您覆盖 equals() 方法时,覆盖 hashcode() 是一种很好的编程习惯,特别是在出现 hash 概念的场景中进入图片。例如 HashMap

    然后您可以进行如下比较:

    public class Test {
        public static void main(String args[]) throws Exception {
            MyClass myFirstClass = new MyClass("John", "Male");
            MyClass mySecondClass = new MyClass("Jessica", "Female");
            Set<MyClass> mySet = new HashSet<MyClass> ();
    
            mySet.add(myFirstClass);
            mySet.add(mySecondClass);
    
            MyClass myDupeClass = new MyClass("Jessica", "Female");
    
            for (MyClass someClass: mySet) {
                if (someClass.equals(myDupeClass)) {
                    System.out.println("Match found for: " + someClass.getName());
                }
            }
        }
    }
    

    输出符合预期

    Match found for: Jessica
    

    【讨论】:

    • 尝试:mySet.contains(myDupeClass) 并返回 null....
    • 不,它不会给出正确的匹配。
    • if(mySet.contains(myDupeClass)) { System.out.println("yes"); } 并且输出是yes
    • 我猜你很幸运,hashCode 生成相同的 int? xyzws.com/javafaq/…
    • 运气? hashCode 必须生成相同的 int,因为对象 mySecondClass 和 myDupeClass 具有相同的数据(姓名和性别)。这没有运气!
    【解决方案4】:

    您可以使用contains() 方法检查 HashSet 是否包含对象。

    您可以使用containsKey() 方法检查 HashMap 是否包含作为键的对象。

    对于任何一个,您都可以覆盖 Object.equals()Object.hashCode()。通常如果你覆盖一个,你也必须覆盖另一个,以满足他们的contracts

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-09
      • 2022-11-09
      • 1970-01-01
      • 2020-06-07
      • 1970-01-01
      • 1970-01-01
      • 2020-08-09
      • 2013-04-22
      相关资源
      最近更新 更多