自定义类的equals有用吗 ?

来源:互联网 发布:淘宝网店可以转让吗 编辑:程序博客网 时间:2024/04/27 22:43

先上来一段代码

import java.util.HashSet;import java.util.Set;/** * 利用set集合查看对象是否相等,因为set里面的元素是不可以重复的 * @author hjm * */public class EqualsSetDemo01 {public static void main(String[] args) {    String str2 = new String("abc");    String str3 = new String("abc");    Set<String> set = new HashSet<String>();    set.add(str3);    set.add(str2);    System.out.println("set的元素有"+set.size()+"个");//1    Set<Person> pset2 = new HashSet<Person>();    Person person1 = new Person("he");    Person person2 = new Person("he");    pset2.add(person1);    pset2.add(person2);    System.out.println("set2的元素有"+pset2.size()+"个");//2}}class Person{private String name;public Person(String name) {    super();    this.name = name;}/* * 用来判断两个person是否相同 */public boolean isSame(Person person) {    if(this.name.equals(person.name))    {        return true;    }    return false;}

}

这里面有一个问题,那就是String类的对象和Person的对象明明都是两个不同的对象,为什么就只有person的set里头是两个,String的set里头元素是一个?

我们之前试图通过自己定义一个boolean方法来判断Person对象是否相等,用到了属性名相等,发现这个方法不起作用,还是一样的是两个元素放进去了,这样子的话,在生活中会出现什么状况呢?比如你发工资给某位员工,按照这个结果你会重复多发一次,即使用到了set集合去重也不行 是不是很坑? 那我们要怎样真正去区别两个不一样元素呢?

看到了String的set集合中只有一个元素,为啥呢?因为String重写了父类即Object的equals方法, 不仅对引用地址进行了比较,还对其内容值进行了昨个比较 ,二者有一即可。

再看我们 的person类,也默认继承了Object类,但是没有重写了父类的equals方法,父类的equals方法只对引用地址进行比较,因为两个person对象开辟了两个空间,自然不是同一个 对象,因此set集合也就自然把他们都放进去了。

所以在Person类中我们要重写equals方法,记住是重写,重写跟重载是不一样的概念。

重载:就是在同一个类中,方法的名字相同,但参数个数、参数的类型不同。

重写:它是指子类和父类的关系,子类重写了父类的方法,但方法名、参数类型、参数个数必须相同

重写更加严格规范。

@Overridepublic boolean equals(Object obj) {    if(this==obj) {        return true;    }    if(obj instanceof Person){        return this.name.equals(((Person) obj).name);    }    return false;}

这么写我们再看下是否可以判断是同一个人了,我们先用list集合的equals方法进行判断是否是同一个人?

    //引入list看下是person的两个实例是否一致    List<Person> pList = new  ArrayList<Person>();    pList.add(person2);    pList.add(person1);    System.out.println("List集合中有"+pList.size());//2    System.out.println(person1.equals(person2));//true 

在list中用equals可以判断是同一个人,那么在set集合中再试一下是否是同一个人呢?

    Person person1 = new Person("he");    Person person2 = new Person("he");    pset2.add(person1);    pset2.add(person2);    System.out.println("set2的元素 有"+pset2.size()+"个");//2   //set2的元素有2个

发现还是两个人,到现在还是无法让person的两个人变成一个人?

很明显,Person这个类在重写equals()方法后,虽然已经支持List,但还不支持Set。要完美支持HashMap,HashSet,LinkedHashMap,ConcurrentHashMap等这些类,不但要重写equals方法,还需要重写hashCode()方法。

所以我们重写了hashcode方法 !

@Overridepublic int hashCode() {    return name.hashCode();}

这下我们再看一下到底是几个人?

Person person1 = new Person("he");Person person2 = new Person("he");pset2.add(person1);pset2.add(person2);System.out.println("set2的元素 有"+pset2.size()+"个");//2//set2的元素有1个

历经千辛万苦 现在已经终于变成一个人了。

总结:当我们在实际业务中需要重写(覆盖)equals方法时,根据规范,我们一定要重写(覆盖)hashCode方法。在实际开发过程中,不建议一上来就重写equals方法,除非你有特殊的需求。

本篇思路来自于https://zhuanlan.zhihu.com/p/27741179
-java那些事儿

我只是大自然的搬运工。

原创粉丝点击