关于 == equals hashcode之间的关系

java基础知识点回顾

1.java中==和equals和hashCode的区别
1) == 是一个操作符 一般用来判断 基本数据类型(byte boolean short char int float long double ) 如果用于比较对象,两个对象指向同一个对象(引用完全相同)则为true,否则为false。
2) equals 是一个方法 该方法可以被重写,在Object类中默认的实现与 == 操作一样。但是equals 方法可以根据自己业务逻辑来定义该方法,用于检查对象的是否相等。注意:在你重写了equals方法,同样要重写hashcode()方法。基于业务的需求重写equals是很好的实践。
下面是String类对于equals的重写

 public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

可以出该方法先比较地址,在一个一个的对比字符来判断是否相等。

3)关于hashcode()和equals方法的关系

3.1)在散列链表 如:HashMap HashTable HashSet 这些本质是散列链表的数据结构中用不到该类,在这种情况下,我们比较对象时,比较是两个对象是否相等,跟hashcode()没有关系。
Person类

    public class Person {
    private String name;
    private String age;

    public Person(String name,String age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (obj == this) {
            return true;
       }
        if (obj.getClass() != this.getClass()) {
            return false;
        }

        Person person = (Person) obj;
        return person.getName().equals(name) && person.getAge().equals(age);
    }

}

测试

@Test
    public void fn1() {
        Person person1 = new Person("wangwu","24");
        Person person2 = new Person("wangwu","24");
        System.out.println("两个对象的否相等:"+person1.equals(person2));
        System.out.println("两个对象的hashCode值:"+person1.hashCode()+","+person2.hashCode());
    }

两个对象的否相等:true
两个对象的hashCode值:1323468230,1645995473

3.2)在散列链表中用到了该类,则该类在实现equals方法时,需要实现hashcode()
注意:1.在这种情况下equals相等的对象,hashcode一定相等。
2.hashcode相等的情况下,equals不一定为true。

我们先来测试一下在不写hashcode的情况下

Person类

public class Person {
    private String name;
    private String age;

    public Person(String name,String age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }


    //--------------没有写hashcode方法-------------

    //------------------------------------------

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (obj == this) {
            return true;
       }
        if (obj.getClass() != this.getClass()) {
            return false;
        }

        Person person = (Person) obj;
        return person.getName().equals(name) && person.getAge().equals(age);
    }

}

测试

    @Test
    public void fn1() {

        Person person1 = new Person("wangwu","24");
        Person person2 = new Person("wangwu","24");
        Person person3 = new Person("zhaoliu","25");
        HashSet<Person> set = new HashSet<>();
        set.add(person1);
        set.add(person2);
        set.add(person3);
        System.out.println("两个对象的否相等:"+person1.equals(person2));
        System.out.println("两个对象的hashCode值:"+person1.hashCode()+","+person2.hashCode());
        System.out.println("set集合:"+set);

    }

两个对象的否相等:true
两个对象的hashCode值:1323468230,1645995473
set集合:[Person [name=wangwu, age=24], Person [name=wangwu, age=24], Person [name=zhaoliu, age=25]]
set集合中是不允许存在重复元素的,但是案例中却出现了相同的元素,所以在重写equals时不写hashcode方法,这个equals比较是失败的
3.4)我们在person类中重写了hashcode

在person类中加上hashcode方法

    //--------------这里加上hashcode方法-------------

    @Override
    public int hashCode() {

        return name.hashCode()^age.hashCode();
    }
    //-------------------------------------------

测试

    @Test
    public void fn1() {

        Person person1 = new Person("wangwu","24");
        Person person2 = new Person("wangwu","24");
        Person person3 = new Person("zhaoliu","25");
        HashSet<Person> set = new HashSet<>();
        set.add(person1);
        set.add(person2);
        set.add(person3);
        System.out.println("两个对象的否相等:"+person1.equals(person2));
        System.out.println("两个对象的hashCode值:"+person1.hashCode()+","+person2.hashCode());
        System.out.println("set集合:"+set);

    }

两个对象的否相等:true
两个对象的hashCode值:-795137437,-795137437
set集合:[Person [name=zhaoliu, age=25], Person [name=wangwu, age=24]]
可以看到 set集合中没有了重复的元素,并且两个相同对象的hashcode值也相同了。这次的equals的比较是成功的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值