代码之家  ›  专栏  ›  技术社区  ›  PAA

Java-Equals和哈希代码比较

  •  -1
  • PAA  · 技术社区  · 5 年前

    我想了解以下情况: equals() hashcode() 这里hashcode总是返回1。

    • 案例1:如果我不重写 equals 然后我得到大小=4
    • 案例2:如果我不重写 等于 ,仅覆盖 hashcode 总是返回1,那么大小=4
    • 案例3:如果我不重写 哈希码 ,仅覆盖 等于 那么大小=4
    • 案例4:如果我超越 等于 哈希码 二者都 哈希码 始终返回1,然后大小=3
    • 案例5:如果我超越 等于 哈希码 二者都 哈希码 将由系统生成,然后大小=3

    有人能解释一下每种情况的内部和案例吗?

    密码

        import java.util.HashMap;
        import java.util.Map;
        
        public class Employee {
            private String name;
            private int age;
        
            public Employee() {
            }
        
            public Employee(String name, int age) {
                super();
                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;
            }
            
            @Override
            public String toString() {
                return "Employee [name=" + name + ", age=" + age + "]";
            }
        
            @Override
            public int hashCode() {
        //      final int prime = 31;
        //      int result = 1;
        //      result = prime * result + age;
        //      result = prime * result + ((name == null) ? 0 : name.hashCode());
                return 1;
            }
        
            @Override
            public boolean equals(Object obj) {
                if (this == obj)
                    return true;
                if (obj == null)
                    return false;
                if (getClass() != obj.getClass())
                    return false;
                Employee other = (Employee) 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;
            }
        }
        
        class Main {
            public static void main(String[] args) {
                Employee prateek = new Employee("Prateek", 32);
                Employee prateek1 = new Employee("Prateek", 32);
                Employee savani = new Employee("Savani", 40);
                Employee karan = new Employee("Karan", 18);
                
                Map<Employee, String> map = new HashMap<>();
                map.put(prateek, "Prateek");
                map.put(savani, "Savani");
                map.put(prateek1, "Prateek");
                map.put(karan, "Karan");
                
                System.out.println("Size = "+map.size());
                System.out.println(map);
            }
        }
    
    1 回复  |  直到 5 年前
        1
  •  2
  •   Bohemian    5 年前

    双方的合同 equals() hashCode() 基本上是: 如果equals()为true,则hashCode()应返回相同的值。

    从javadoc:

    如果根据equals(Object)方法,两个对象相等,那么对这两个对象中的每一个调用hashCode方法必须产生相同的整数结果。

    如果不是这样,则基于哈希的集合/操作的行为是未定义的。

        2
  •  0
  •   scottb    5 年前

    波希米亚人的答案完全正确。例如,以下 hashCode() 方法满足合同要求,程序将正确运行:

    public int hashCode() {
        return 42;
    }
    

    使用这种方法的程序之所以正确,是因为 hashCode() 满足:相同的实例将始终具有相同的哈希代码。

    但这 hashCode() 方法是一个问题,因为它为相等和不相等的实例返回相同的哈希。为了获得最佳性能,开发人员应该尝试编写 hashCode() 为不相等的实例生成不同int值的方法。这不是合同要求的 hashCode() 但如果良好的表现很重要,这一点至关重要。

    例如,使用上述方法,添加到 HashMap 将分配到同一个桶中。结果是性能下降。最好的散列函数可以很好地将不同的实例分布到不同的存储桶中。因此,如果在HashMap中使用这些实例,您的案例#2可能会导致严重的性能问题。