Java ==、equals、hashcode的区别

来源:互联网 发布:单片机led流水灯程序 编辑:程序博客网 时间:2024/05/02 01:21

1、== 对于基本变量,判断其值是否相同;对于引用对象,判断其指向的内存地址是否相同。
2、equals 只能应用于引用对象,默认和==的作用相同,如果像String一样继承的话,则可以实现自定义的比较。
3、HashCode仅在Hash容器中使用,用于决定将要插入对象的位置。

package com.demo.test;import java.util.HashSet;public class EqualDemo {    static class Person implements Cloneable {        public String idcard;        public Person(String idcard) {            this.idcard = idcard;        }        //super.clone方法是protected的,这里要将它的可见性手动改为public, 并且删除throws CloneNotSupportedException        @Override        public Object clone() {            return new Person(idcard);        }    }    static class NewPerson {        public String idcard;        public NewPerson(String idcard) {            this.idcard = idcard;        }        @Override        public Object clone() {            return new NewPerson(idcard);        }        @Override        public boolean equals(Object obj) {            if(obj instanceof NewPerson) {                if(idcard != null && idcard.equals(((NewPerson) obj).idcard)) {                    return true;                }            }            return false;        }    }    static class EvolutionPerson {        public String idcard;        public EvolutionPerson(String idcard) {            this.idcard = idcard;        }        @Override        public Object clone() {            return new EvolutionPerson(idcard);        }        @Override        public boolean equals(Object obj) {            if(obj instanceof EvolutionPerson) {                if(idcard != null && idcard.equals(((EvolutionPerson) obj).idcard)) {                    return true;                }            }            return false;        }        @Override        public int hashCode() {            return idcard.hashCode();        }    }    public static void main(String[] args) {        String str1 = "123";        String str2 = "123";        String str3 = new String("123");        System.out.println(str1 == str2);//true        System.out.println(str1.equals(str2));//true, 这说明对于基本类型变量,equal比较其值,值相同则认为一致//      System.out.println(str1 == 123);//Error: Incompatible operand types String and int        System.out.println(str1.equals(123));//false, 在java中,如果类型不一样,肯定不同。如果是javascript则会自动转化        System.out.println(str1 == str3);//false, 字符串常量在常量池中,而new的字符串存放在堆中,==只比较地址        System.out.println(str1.equals(str3));//true, string复写了equls方法,先比较==,如果不等,再一个一个字符的进行比较        Person p1 = new Person("123");        Person p2 = p1;        Person p3 = (Person) p1.clone();        System.out.println(p1.equals(p2));//true, 这说明对于对象equal比较的是引用类型变量的地址,只有其指向的地址一致,equal才会返回true        System.out.println(p1.equals(p3));//false, 这说明即使引用类型变量的内部变量都一样,地址不一样还是认为是不同的        NewPerson np1 = new NewPerson("123");        NewPerson np2 = (NewPerson) np1.clone();        System.out.println(np1.equals(np2));//true,因为已经覆写了equals方法        /*           在HashMap中,查找key的比较顺序为:         1、计算对象的Hash Code,看在表中是否存在。         2、检查对应Hash Code位置中的对象和当前对象是否相等。         3、如果Hash Code相等,但equals不等,则会放到跟该Hash Code有关地址上的一个链式结构中         */        HashSet<NewPerson> npSet = new HashSet<NewPerson>();        npSet.add(np1);        npSet.add(np2);        System.out.println(npSet.size());//2, 说明2个对象即使equals返回true,但是还被set判断为不想等        EvolutionPerson ep1 = new EvolutionPerson("123");        EvolutionPerson ep2 = (EvolutionPerson) ep1.clone();        HashSet<EvolutionPerson> epSet = new HashSet<EvolutionPerson>();        epSet.add(ep1);        epSet.add(ep2);        System.out.println(epSet.size());//1, 说明在HashSet中只有hashCode和equals同时相同,才会被判定为一个对象    }}
1 0