Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么java中具有相同值的两个对象的hashcode()不同?_Java_Hashcode - Fatal编程技术网

为什么java中具有相同值的两个对象的hashcode()不同?

为什么java中具有相同值的两个对象的hashcode()不同?,java,hashcode,Java,Hashcode,Object-1: Employee employee1 = new Employee("AB12","Dhruv", 24); Employee employee2 = new Employee("AB12", "Dhruv", 24); true employee1.hashCode(): 511833308 employee3.hashCode(): 511833308 false employee2.hashCode(): 1297685781 true employee1.has

Object-1:

Employee employee1 = new Employee("AB12","Dhruv", 24);
Employee employee2 = new Employee("AB12", "Dhruv", 24);
true
employee1.hashCode(): 511833308
employee3.hashCode(): 511833308
false
employee2.hashCode(): 1297685781
true
employee1.hashCode(): 128107556
employee3.hashCode(): 128107556
false
employee2.hashCode(): 128107556
true
employee1.hashCode(): 66066760
employee1.hashCode() again: 66069457
employee3.hashCode(): 66073797
false
employee2.hashCode(): 66074882
true
employee1.hashCode(): 511833308
employee3.hashCode(): 511833308
true
employee2.hashCode(): 1297685781
true
employee1.hashCode(): 128107556
employee3.hashCode(): 128107556
true
employee2.hashCode(): 128107556
Object-2:

Employee employee1 = new Employee("AB12","Dhruv", 24);
Employee employee2 = new Employee("AB12", "Dhruv", 24);
true
employee1.hashCode(): 511833308
employee3.hashCode(): 511833308
false
employee2.hashCode(): 1297685781
true
employee1.hashCode(): 128107556
employee3.hashCode(): 128107556
false
employee2.hashCode(): 128107556
true
employee1.hashCode(): 66066760
employee1.hashCode() again: 66069457
employee3.hashCode(): 66073797
false
employee2.hashCode(): 66074882
true
employee1.hashCode(): 511833308
employee3.hashCode(): 511833308
true
employee2.hashCode(): 1297685781
true
employee1.hashCode(): 128107556
employee3.hashCode(): 128107556
true
employee2.hashCode(): 128107556
输出

HASH CODE FOR EMPLOYEE 1 :  43704527 
HASH CODE FOR EMPLOYEE 2 : 158893348

除非
@重写
hashCode()
方法并实现自己的版本,否则类将使用从
对象继承的默认方法,该方法会为每个对象实例生成唯一的hashCode


如果希望
equals
和/或
hashCode
只关心对象的成员,则需要自己编写实现。

因为您没有重写
hashCode
来替换默认实现。重写
equals
不会改变
hashCode
(如果重写
equals
,则几乎总是必须同时重写这两者)

hashCode
说明了
对象中的默认实现:

在合理可行的情况下,hashCode方法由 类对象确实为不同的对象返回不同的整数。(本 通常通过转换 对象转换为整数,但此实现技术不适用 Java所要求的™ 编程语言。)

因此,除非替换
hashCode
,否则对于不同的实例,即使它们相等,也会得到不同的整数(通常)

你可以这样做

 @Override
        public int hashCode() {
            return hashId;
        }

从以下几点来看:

  • 在Java应用程序的执行过程中,每当在同一对象上多次调用hashCode方法时,只要没有修改对象上的equals比较中使用的信息,hashCode方法必须始终返回相同的整数。从应用程序的一次执行到同一应用程序的另一次执行,该整数不必保持一致
  • 如果根据equals(Object)方法两个对象相等,那么对两个对象中的每一个调用hashCode方法必须产生相同的整数结果
  • 根据equals(java.lang.Object)方法,如果两个对象不相等,则对这两个对象中的每一个调用hashCode方法都必须产生不同的整数结果,这不是必需的。但是,程序员应该知道,为不相等的对象生成不同的整数结果可能会提高哈希表的性能
  • 只要是合理可行的,类对象定义的hashCode方法确实会为不同的对象返回不同的整数。(hashCode在某个时间点可能实现为对象内存地址的函数,也可能不实现。)
  • 现在,查看以下代码及其输出:

    class MyEmployee {
        String code;
        String name;
        int age;
    
        public MyEmployee(String code, String name, int age) {
            super();
            this.code = code;
            this.name = name;
            this.age = age;
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            MyEmployee employee1 = new MyEmployee("AB12", "Dhruv", 24);
            MyEmployee employee2 = new MyEmployee("AB12", "Dhruv", 24);
            MyEmployee employee3 = employee1;
            System.out.println(employee1.equals(employee3));
            System.out.println("employee1.hashCode(): " + employee1.hashCode());
            System.out.println("employee3.hashCode(): " + employee3.hashCode());
            System.out.println(employee1.equals(employee2));
            System.out.println("employee2.hashCode(): " + employee2.hashCode());
        }
    }
    
    class MyEmployee {
        String code;
        String name;
        int age;
    
        public MyEmployee(String code, String name, int age) {
            super();
            this.code = code;
            this.name = name;
            this.age = age;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            MyEmployee other = (MyEmployee) obj;
            if (code == null) {
                if (other.code != null)
                    return false;
            } else if (!code.equals(other.code))
                return false;
            return true;
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            MyEmployee employee1 = new MyEmployee("AB12", "Dhruv", 24);
            MyEmployee employee2 = new MyEmployee("AB12", "Dhruv", 24);
            MyEmployee employee3 = employee1;
            System.out.println(employee1.equals(employee3));
            System.out.println("employee1.hashCode(): " + employee1.hashCode());
            System.out.println("employee3.hashCode(): " + employee3.hashCode());
            System.out.println(employee1.equals(employee2));
            System.out.println("employee2.hashCode(): " + employee2.hashCode());
        }
    }
    
    输出:

    Employee employee1 = new Employee("AB12","Dhruv", 24);
    
    Employee employee2 = new Employee("AB12", "Dhruv", 24);
    
    true
    employee1.hashCode(): 511833308
    employee3.hashCode(): 511833308
    false
    employee2.hashCode(): 1297685781
    
    true
    employee1.hashCode(): 128107556
    employee3.hashCode(): 128107556
    false
    employee2.hashCode(): 128107556
    
    true
    employee1.hashCode(): 66066760
    employee1.hashCode() again: 66069457
    employee3.hashCode(): 66073797
    false
    employee2.hashCode(): 66074882
    
    true
    employee1.hashCode(): 511833308
    employee3.hashCode(): 511833308
    true
    employee2.hashCode(): 1297685781
    
    true
    employee1.hashCode(): 128107556
    employee3.hashCode(): 128107556
    true
    employee2.hashCode(): 128107556
    
    由于
    employee3
    指向的对象与
    employee1
    指向的对象相同,因此当
    employee2
    指向另一个对象时(尽管它的内容相同,关键字
    new
    将在内存中创建一个单独的对象),因此,您可能很少从文档状态中获得与上述第4点相同的hashcode:class对象定义的hashcode方法,只要合理可行,class对象定义的hashcode方法会为不同的对象返回不同的整数。

    您必须重写
    hashCode
    方法,该方法应为具有相同内容的两个对象返回相同的hashCode,例如

    class MyEmployee {
        String code;
        String name;
        int age;
    
        public MyEmployee(String code, String name, int age) {
            super();
            this.code = code;
            this.name = name;
            this.age = age;
        }
    
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + age;
            result = prime * result + ((code == null) ? 0 : code.hashCode());
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            return result;
        }   
    }
    
    public class Main {
        public static void main(String[] args) {
            MyEmployee employee1 = new MyEmployee("AB12", "Dhruv", 24);
            MyEmployee employee2 = new MyEmployee("AB12", "Dhruv", 24);
            MyEmployee employee3 = employee1;
            System.out.println(employee1.equals(employee3));
            System.out.println("employee1.hashCode(): " + employee1.hashCode());
            System.out.println("employee3.hashCode(): " + employee3.hashCode());
            System.out.println(employee1.equals(employee2));
            System.out.println("employee2.hashCode(): " + employee2.hashCode());
        }
    }
    
    输出:

    Employee employee1 = new Employee("AB12","Dhruv", 24);
    
    Employee employee2 = new Employee("AB12", "Dhruv", 24);
    
    true
    employee1.hashCode(): 511833308
    employee3.hashCode(): 511833308
    false
    employee2.hashCode(): 1297685781
    
    true
    employee1.hashCode(): 128107556
    employee3.hashCode(): 128107556
    false
    employee2.hashCode(): 128107556
    
    true
    employee1.hashCode(): 66066760
    employee1.hashCode() again: 66069457
    employee3.hashCode(): 66073797
    false
    employee2.hashCode(): 66074882
    
    true
    employee1.hashCode(): 511833308
    employee3.hashCode(): 511833308
    true
    employee2.hashCode(): 1297685781
    
    true
    employee1.hashCode(): 128107556
    employee3.hashCode(): 128107556
    true
    employee2.hashCode(): 128107556
    
    上面给出的
    hashCode
    的实现为
    employee1
    employee2
    生成相同的hashCode,即使
    等于
    返回
    false
    (从文档中选择上面提到的点3

    重写
    hashCode
    的错误方法可能会导致相同的对象返回不同的hashCode,例如

    class MyEmployee {
        String code;
        String name;
        int age;
    
        public MyEmployee(String code, String name, int age) {
            super();
            this.code = code;
            this.name = name;
            this.age = age;
        }
    
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + age;
            result = prime * result + ((code == null) ? 0 : (int) (code.length() * (Math.random() * 100)));
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            return result;
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            MyEmployee employee1 = new MyEmployee("AB12", "Dhruv", 24);
            MyEmployee employee2 = new MyEmployee("AB12", "Dhruv", 24);
            MyEmployee employee3 = employee1;
            System.out.println(employee1.equals(employee3));
            System.out.println("employee1.hashCode(): " + employee1.hashCode());
            System.out.println("employee1.hashCode() again: " + employee1.hashCode());
            System.out.println("employee3.hashCode(): " + employee3.hashCode());
            System.out.println(employee1.equals(employee2));
            System.out.println("employee2.hashCode(): " + employee2.hashCode());
        }
    }
    
    输出:

    Employee employee1 = new Employee("AB12","Dhruv", 24);
    
    Employee employee2 = new Employee("AB12", "Dhruv", 24);
    
    true
    employee1.hashCode(): 511833308
    employee3.hashCode(): 511833308
    false
    employee2.hashCode(): 1297685781
    
    true
    employee1.hashCode(): 128107556
    employee3.hashCode(): 128107556
    false
    employee2.hashCode(): 128107556
    
    true
    employee1.hashCode(): 66066760
    employee1.hashCode() again: 66069457
    employee3.hashCode(): 66073797
    false
    employee2.hashCode(): 66074882
    
    true
    employee1.hashCode(): 511833308
    employee3.hashCode(): 511833308
    true
    employee2.hashCode(): 1297685781
    
    true
    employee1.hashCode(): 128107556
    employee3.hashCode(): 128107556
    true
    employee2.hashCode(): 128107556
    
    这是覆盖
    hashCode
    的错误方法,因为在Java应用程序执行期间多次调用同一对象上的
    hashCode
    必须一致地返回相同的整数(检查上述文档中提到的点1

    现在,查看以下代码及其输出:

    class MyEmployee {
        String code;
        String name;
        int age;
    
        public MyEmployee(String code, String name, int age) {
            super();
            this.code = code;
            this.name = name;
            this.age = age;
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            MyEmployee employee1 = new MyEmployee("AB12", "Dhruv", 24);
            MyEmployee employee2 = new MyEmployee("AB12", "Dhruv", 24);
            MyEmployee employee3 = employee1;
            System.out.println(employee1.equals(employee3));
            System.out.println("employee1.hashCode(): " + employee1.hashCode());
            System.out.println("employee3.hashCode(): " + employee3.hashCode());
            System.out.println(employee1.equals(employee2));
            System.out.println("employee2.hashCode(): " + employee2.hashCode());
        }
    }
    
    class MyEmployee {
        String code;
        String name;
        int age;
    
        public MyEmployee(String code, String name, int age) {
            super();
            this.code = code;
            this.name = name;
            this.age = age;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            MyEmployee other = (MyEmployee) obj;
            if (code == null) {
                if (other.code != null)
                    return false;
            } else if (!code.equals(other.code))
                return false;
            return true;
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            MyEmployee employee1 = new MyEmployee("AB12", "Dhruv", 24);
            MyEmployee employee2 = new MyEmployee("AB12", "Dhruv", 24);
            MyEmployee employee3 = employee1;
            System.out.println(employee1.equals(employee3));
            System.out.println("employee1.hashCode(): " + employee1.hashCode());
            System.out.println("employee3.hashCode(): " + employee3.hashCode());
            System.out.println(employee1.equals(employee2));
            System.out.println("employee2.hashCode(): " + employee2.hashCode());
        }
    }
    
    输出:

    Employee employee1 = new Employee("AB12","Dhruv", 24);
    
    Employee employee2 = new Employee("AB12", "Dhruv", 24);
    
    true
    employee1.hashCode(): 511833308
    employee3.hashCode(): 511833308
    false
    employee2.hashCode(): 1297685781
    
    true
    employee1.hashCode(): 128107556
    employee3.hashCode(): 128107556
    false
    employee2.hashCode(): 128107556
    
    true
    employee1.hashCode(): 66066760
    employee1.hashCode() again: 66069457
    employee3.hashCode(): 66073797
    false
    employee2.hashCode(): 66074882
    
    true
    employee1.hashCode(): 511833308
    employee3.hashCode(): 511833308
    true
    employee2.hashCode(): 1297685781
    
    true
    employee1.hashCode(): 128107556
    employee3.hashCode(): 128107556
    true
    employee2.hashCode(): 128107556
    
    由于
    employee1.equals(employee2)
    返回
    true
    ,因此hashcode也应返回相同的值(检查上述文档中的点2)。但是,
    employee1
    employee2
    的hashcode值不同,这是不正确的。这种差异是因为我们没有重写
    hashCode
    方法。因此,无论何时重写
    equals
    ,都应该以正确的方式重写
    hashCode

    最后,下面给出了实现
    hashCode
    equals
    的正确方法:

    class MyEmployee {
        String code;
        String name;
        int age;
    
        public MyEmployee(String code, String name, int age) {
            super();
            this.code = code;
            this.name = name;
            this.age = age;
        }
    
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + age;
            result = prime * result + ((code == null) ? 0 : code.hashCode());
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            return result;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            MyEmployee other = (MyEmployee) obj;
            if (age != other.age)
                return false;
            if (code == null) {
                if (other.code != null)
                    return false;
            } else if (!code.equals(other.code))
                return false;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            return true;
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            MyEmployee employee1 = new MyEmployee("AB12", "Dhruv", 24);
            MyEmployee employee2 = new MyEmployee("AB12", "Dhruv", 24);
            MyEmployee employee3 = employee1;
            System.out.println(employee1.equals(employee3));
            System.out.println("employee1.hashCode(): " + employee1.hashCode());
            System.out.println("employee3.hashCode(): " + employee3.hashCode());
            System.out.println(employee1.equals(employee2));
            System.out.println("employee2.hashCode(): " + employee2.hashCode());
        }
    }
    
    输出:

    Employee employee1 = new Employee("AB12","Dhruv", 24);
    
    Employee employee2 = new Employee("AB12", "Dhruv", 24);
    
    true
    employee1.hashCode(): 511833308
    employee3.hashCode(): 511833308
    false
    employee2.hashCode(): 1297685781
    
    true
    employee1.hashCode(): 128107556
    employee3.hashCode(): 128107556
    false
    employee2.hashCode(): 128107556
    
    true
    employee1.hashCode(): 66066760
    employee1.hashCode() again: 66069457
    employee3.hashCode(): 66073797
    false
    employee2.hashCode(): 66074882
    
    true
    employee1.hashCode(): 511833308
    employee3.hashCode(): 511833308
    true
    employee2.hashCode(): 1297685781
    
    true
    employee1.hashCode(): 128107556
    employee3.hashCode(): 128107556
    true
    employee2.hashCode(): 128107556
    

    可能是因为您的Employee类没有重写
    hashCode
    方法,所以它从java.lang.Object继承了该方法,该方法通常基于内部内存地址。这不是一个很好的问题,但尽管如此,这是一个非常好和彻底的答案。非常感谢。1+感谢您的精彩解释