自定义类的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那些事儿
我只是大自然的搬运工。
- 自定义类的equals有用吗 ?
- 自定义类型的equals方法的实现
- HashSet 的使用 自定义hashCode和equals
- 一个非常有用的自定义聚集函数
- abgularjs 自定义标签感觉有用的东西
- 记录几个比较有用的自定义viewpager
- 很有用的自定义View详解教程
- 最有用的idea快捷键整理(自定义)
- String类的equals
- equals和==的区别,以及如何将自定义类作为HashMap的Key
- android的自定义控件及自定义属性 - 相当有用呢
- java中set\map自定义去重依据(重载Bean类的hashcode和equals)
- 使用HashMap,如果key是自定义的类,就必须重写hashcode()和equals()。
- 使用HashMap,如果key是自定义的类,就必须重写hashcode()和equals()。
- 对于自定义类,重写equals方法和hashCode方法的技巧
- HashMap中如果key是自定义的类,为什么重写hashcode()和equals()
- 黑马程序员--哈希集合中的hashCode和equals的详解。。感觉挺有用的
- 有用的工具类
- maven----pom.xml详解
- MyString
- C#SQLServer中存储过程的调用
- 选美
- 迷宫游戏
- 自定义类的equals有用吗 ?
- linux修改系统时间
- 调用子类构造器来初始化子类对象时,父类构造器会在子类构造器之前执行
- HDU
- CVTE水果问题
- HDU 6058 Kanade's sum(多校3)
- linux的环境变量
- 排序之三:插入排序
- TCP 简单理解