重写map中equals方法
- 格式:docx
- 大小:12.17 KB
- 文档页数:3
标题:Java对象重写equals方法一、什么是equals方法在Java编程语言中,equals()是一个用来比较两个对象是否相等的方法。
在Object类中,equals()的默认实现是使用“==”运算符来比较两个对象的引用位置区域是否相同。
但是在实际开发中,我们通常需要根据对象的内容来判断它们是否相等。
我们经常需要重写equals()方法来实现自定义的对象比较逻辑。
二、为什么要重写equals方法1. 当我们自定义一个类时,对象的相等性判断通常是根据对象的属性值来确定的,而不是根据对象的引用位置区域。
我们需要重写equals()方法来实现对象的自定义相等性比较逻辑。
2. 在使用一些集合类(如HashMap、HashSet等)时,这些类会依赖equals()方法来判断对象是否相等。
如果我们不重写equals()方法,集合类中的一些操作可能会出现意想不到的结果。
三、如何重写equals方法1. 重写equals()方法的基本原则是:自反性、对称性、传递性和一致性。
也就是说,对于任意非null的引用值x,x.equals(x)应该返回true;对称性和传递性类似;一致性指的是如果两个对象的属性值没有发生改变,那么它们的equals()方法的返回值也应该保持一致。
2. 在重写equals()方法时,通常需要按照以下步骤进行:a. 首先判断是否是同一对象,如果是直接返回true;b. 接下来判断是否是null或者不是同一个类的实例,如果是直接返回false;c. 然后将参数对象转换成当前对象的类型;d. 最后逐个比较对象的属性值,如果所有属性值都相等,就返回true,否则返回false。
3. 在实际开发中,可以借助一些工具类来帮助我们重写equals()方法,如Apache Commons Lang库中的EqualsBuilder类和HashCodeBuilder类。
四、重写equals方法的注意事项1. 在重写equals()方法时,一定要注意确保满足上文提到的自反性、对称性、传递性和一致性原则,否则可能会导致一些问题。
JavaMap操作Map:键必须是唯⼀同步⽅法:Map m = Collections.synchronizedMap(new TreeMap(...));Hashtable:基于散列表的实现 允许空键空值 线程安全HashMap:基于散列表的实现 允许空键空值 线程不安全 (与Hashtable基本⼀致)TreeMap: 基于红⿊树数据结构的实现 不允许空键空值 线程不安全WeakHashMap:改进的HashMap,它对key实⾏“弱引⽤”,如果⼀个key不再被外部所引⽤,那么该key可以被GC回收。
在除需要排序时使⽤TreeSet,TreeMap外,都应使⽤HashSet,HashMap,因为他们的效率更⾼。
HashTable:import java.util.Hashtable;public class Main {public static void main(String[] args) {Hashtable ht = new Hashtable();ht.put(new A(60000) , "11");ht.put(new A(87563) , "22");ht.put(new A(1232) , new B());System.out.println(ht);//只要两个对象通过equals⽐较返回true,//Hashtable就认为它们是相等的value。
//由于Hashtable中有⼀个B对象,//它与任何对象通过equals⽐较都相等,所以下⾯输出true。
System.out.println(ht.containsValue("测试字符串")); //①//只要两个A对象的count相等,它们通过equals⽐较返回true,且hashCode相等//Hashtable即认为它们是相同的key,所以下⾯输出true。
Java重写equals⽅法(重点讲解)为什么equals()⽅法要重写?判断两个对象在逻辑上是否相等,如根据类的成员变量来判断两个类的实例是否相等,⽽继承Object中的equals⽅法只能判断两个引⽤变量是否是同⼀个对象。
这样我们往往需要重写equals()⽅法。
我们向⼀个没有重复对象的集合中添加元素时,集合中存放的往往是对象,我们需要先判断集合中是否存在已知对象,这样就必须重写equals⽅法。
怎样重写equals()⽅法?重写equals⽅法的要求:1、⾃反性:对于任何⾮空引⽤x,x.equals(x)应该返回true。
2、对称性:对于任何引⽤x和y,如果x.equals(y)返回true,那么y.equals(x)也应该返回true。
3、传递性:对于任何引⽤x、y和z,如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)也应该返回true。
4、⼀致性:如果x和y引⽤的对象没有发⽣变化,那么反复调⽤x.equals(y)应该返回同样的结果。
5、⾮空性:对于任意⾮空引⽤x,x.equals(null)应该返回false。
1、⾃反性原则在JavaBean中,经常会覆写equals⽅法,从⽽根据实际业务情况来判断两个对象是否相等,⽐如我们写⼀个person类,根据姓名来判断两个person类实例对象是否相等。
代码如下:1public class Person {2private String name;34public Person(String name) { = name;6 }78public String getName() {9return name;10 }1112public void setName(String name) { = name;14 }1516 @Override17public boolean equals(Object obj) {18if (obj instanceof Person) {19 Person person = (Person) obj;20return name.equalsIgnoreCase(person.getName().trim());21 }22return false;23 }2425public static void main(String[] args) {26 Person p1 = new Person("张三");27 Person p2 = new Person("张三 ");28 List<Person> list = new ArrayList<Person>();29 list.add(p1);30 list.add(p2);31 System.out.println("是否包含张三:" + list.contains(p1));32 System.out.println("是否包含张三:" + list.contains(p2));33 }34 }list中含有这个⽣成的person对象,结果应该为true,但是实际结果:这⾥考虑了字符串空格的问题,去除前后的空格。
Java⽐较两个对象中全部属性值是否相等的⽅法例如下述Java类:import java.io.Serializable;import java.util.List;public class Bean_Topology implements Serializable {private static final long serialVersionUID = 1L;public static long getSerialversionuid() {return serialVersionUID;}private Long topology_pk;private String topology_id;public String getTopology_id() {return topology_id;}public void setTopology_id(String topology_id) {this.topology_id = topology_id;}public Long getTopology_pk() {return topology_pk;}public void setTopology_pk(Long topology_pk) {this.topology_pk = topology_pk;}@Overridepublic String toString() {return "当前拓扑的PK为:" + topology_pk + ",ID为:" + topology_id;}}如下想判断下⾯两个对象中全部属性值是否⼀致时,有哪些办法呢?Bean_Topology topology1 = new Bean_Topology();topology1.setTopology_id("1");Bean_Topology topology2 = new Bean_Topology();topology2.setTopology_pk(1L);topology2.setTopology_id("1");⽅法⼀:重写Bean_Topology的equals⽅法和hashcode⽅法,代码如下:@Overridepublic boolean equals(Object obj) {if (this == obj) {return true;}if (obj == null || getClass() != obj.getClass()) {return false;}Bean_Topology topology = (Bean_Topology) obj;if (topology_pk == null) {if (topology.topology_pk != null) {return false;}}else if (!topology_pk.equals(topology.topology_pk)) {return false;}if (topology_id == null) {if (topology.topology_id != null) {return false;}}else if (!topology_id.equals(topology.topology_id)) {return false;}return true;}@Overridepublic int hashCode() {return topology_pk.hashCode()+topology_id.hashCode();}测试代码如下:if(topology1.equals(topology2)) {System.out.println("对象1与对象2的属性值⽆差异。
HashSet与HashMap的区别HashSet与HashMap的区别1.HashSet: HashSet实现了Set接⼝,它不允许集合中出现重复元素。
当我们提到HashSet时,第⼀件事就是在将对象存储在HashSet之前,要确保重写hashCode()⽅法和equals()⽅法,这样才能⽐较对象的值是否相等,确保集合中没有储存相同的对象。
如果不重写上述两个⽅法,那么将使⽤下⾯⽅法默认实现: public boolean add(Object obj)⽅法⽤在Set添加元素时,如果元素值重复时返回 "false",如果添加成功则返回"true"2.HashMap: HashMap实现了Map接⼝,Map接⼝对键值对进⾏映射。
Map中不允许出现重复的键(Key)。
Map接⼝有两个基本的实现TreeMap和HashMap。
TreeMap保存了对象的排列次序,⽽HashMap不能。
HashMap可以有空的键值对(Key(null)-Value(null))HashMap是⾮线程安全的(⾮Synchronize),要想实现线程安全,那么需要调⽤collections类的静态⽅法synchronizeMap()实现。
public Object put(Object Key,Object value)⽅法⽤来将元素添加到map中。
3.HashSet与HashMap的区别:(1)HashMapa.实现了Map接⼝b.存储键值对c.调⽤put()向map中添加元素d.HashMap使⽤键(Key)计算Hashcodee.HashMap相对于HashSet较快,因为它是使⽤唯⼀的键获取对象(2)HashSeta.实现Set接⼝b.仅存储对象c.调⽤add()⽅法向Set中添加元素d.HashSet使⽤成员对象来计算hashcode值,对于两个对象来说hashcode可能相同,所以equals()⽅法⽤来判断对象的相等性,如果两个对象不同的话,那么返回falsee.HashSet较HashMap来说⽐较慢。
java map的多种方法Java中的Map是一种常用的数据结构,它可以存储键值对(key-value pairs)的集合。
在Java中,提供了多种方法来操作和使用Map,本文将介绍一些常用的方法。
1. 创建Map对象:在Java中,可以使用HashMap、TreeMap、LinkedHashMap等类来创建Map对象。
例如,可以使用HashMap来创建一个空的Map对象:```Map<String, Integer> map = new HashMap<>();```2. 添加元素:可以使用put()方法向Map中添加元素。
put()方法接受两个参数,第一个参数是键(key),第二个参数是值(value)。
例如,可以向上面创建的Map对象中添加一个键值对:```map.put("apple", 10);```3. 获取元素:可以使用get()方法从Map中获取指定键对应的值。
get()方法接受一个参数,即要获取的键。
例如,可以获取上面Map对象中键为"apple"的值:```int value = map.get("apple");```4. 判断键是否存在:可以使用containsKey()方法来判断Map中是否包含指定的键。
containsKey()方法接受一个参数,即要判断的键。
例如,可以判断上面Map对象中是否包含键"apple":```boolean contains = map.containsKey("apple");```5. 判断值是否存在:可以使用containsValue()方法来判断Map中是否包含指定的值。
containsValue()方法接受一个参数,即要判断的值。
例如,可以判断上面Map对象中是否包含值10:```boolean contains = map.containsValue(10);```6. 删除元素:可以使用remove()方法从Map中删除指定键对应的键值对。
map方法的四个参数标题:深入解析map方法的四个参数引言概述:在JavaScript中,map()方法是数组对象的一个常用方法,它能够对数组中的每个元素进行操作并返回一个新的数组。
map()方法接受四个参数,包括回调函数、this值、当前索引以及原数组。
本文将深入探讨map()方法的四个参数,帮助读者更好地理解和应用该方法。
正文内容:1. 回调函数参数1.1 回调函数的定义回调函数是作为参数传递给map()方法的函数。
它可以接受三个参数:当前元素的值、当前元素的索引和原数组本身。
1.2 使用回调函数的目的回调函数的作用是定义对每个元素的操作。
通过在回调函数中编写逻辑,我们可以对每个元素进行处理、修改或者生成新的值。
2. this值参数2.1 this值的含义this值指定了回调函数中的this关键字的值。
它决定了在回调函数中如何使用this关键字,以及this关键字所指向的对象。
2.2 this值的默认设置如果不传递this值参数,map()方法将使用全局对象作为默认的this值。
但是,建议在使用map()方法时显式地指定this值,以避免不必要的问题。
3. 当前索引参数3.1 当前索引的作用当前索引参数表示当前元素在数组中的索引位置。
它可以用于在回调函数中进行条件判断、计算或者其他操作。
3.2 使用当前索引的注意事项当前索引参数在一些特定的情况下非常有用,但在一般情况下,我们应该谨慎使用它。
过度依赖索引可能导致代码可读性下降和维护困难。
4. 原数组参数4.1 原数组的作用原数组参数表示调用map()方法的数组本身。
它可以在回调函数中用于访问和操作原数组的其他元素。
4.2 使用原数组的注意事项在回调函数中修改原数组可能会导致不可预料的结果,因此我们应该避免直接修改原数组。
如果需要修改原数组,应该使用其他方法或者创建一个新的数组。
总结:综上所述,map()方法的四个参数分别是回调函数、this值、当前索引和原数组。
idea 自动生成hashcode 和equals 方法全文共四篇示例,供读者参考第一篇示例:在Java程序设计中,我们经常需要用到对象之间的比较和相等性检查。
为了实现这些功能,我们需要重写对象的hashCode()和equals()方法。
这两个方法是Object类中的两个重要方法,hashCode()方法用于返回对象的哈希码,equals()方法用于比较两个对象是否相等。
对于开发人员来说,手动编写hashCode()和equals()方法可能会比较繁琐和耗时。
有一种更加便捷的方法,即使用IDEA工具自动生成这两个方法。
在本文中,我们将介绍如何使用IDEA工具自动生成hashCode()和equals()方法。
打开IDEA工具,并创建一个新的Java类。
在该类中定义需要重写hashCode()和equals()方法的对象。
接着,按照以下步骤操作:1. 在IDEA工具中,选中需要重写hashCode()和equals()方法的类,右键点击,选择"Generate" -> "HashCode and Equals"选项。
2. 在弹出的对话框中,IDEA会显示要重写的类中的所有成员变量。
我们可以根据需要选择哪些成员变量要参与hashCode()和equals()方法的计算。
3. 点击"OK"按钮,IDEA会自动生成hashCode()和equals()方法。
生成的hashCode()和equals()方法会根据所选的成员变量进行计算,确保对象的唯一性和相等性检查。
这样可以避免出现由于hashCode()和equals()方法不准确导致的程序错误。
需要注意的是,如果需要修改生成的hashCode()和equals()方法,可以手动编辑这两个方法的代码。
IDEA也提供了快捷键和代码模板,可以帮助我们更轻松地修改和优化这些方法。
第二篇示例:在Java编程中,我们经常需要重写hashCode()和equals()方法来确保对象在集合中的正确功能。
重写hashCode()和equals()⽅法详细介绍⽬录如何重写equals()⽅法如何重写hashCode()⽅法重写equals()⽽不重写hashCode()的风险总结hashCode()和equals()⽅法可以说是Java完全⾯向对象的⼀⼤特⾊.它为我们的编程提供便利的同时也带来了很多危险.这篇⽂章我们就讨论⼀下如何正解理解和使⽤这2个⽅法.如何重写equals()⽅法如果你决定要重写equals()⽅法,那么你⼀定要明确这么做所带来的风险,并确保⾃⼰能写出⼀个健壮的equals()⽅法.⼀定要注意的⼀点是,在重写equals()后,⼀定要重写hashCode()⽅法.具体原因稍候再进⾏说明.我们先看看 JavaSE 7 Specification中对equals()⽅法的说明:·It is reflexive: for any non-null reference value x, x.equals(x) should return true.·It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.·It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.·It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.·For any non-null reference value x, x.equals(null) should return false.这段话⽤了很多离散数学中的术数.简单说明⼀下:1. ⾃反性:A.equals(A)要返回true.2. 对称性:如果A.equals(B)返回true, 则B.equals(A)也要返回true.3. 传递性:如果A.equals(B)为true, B.equals(C)为true, 则A.equals(C)也要为true. 说⽩了就是 A = B , B = C , 那么A = C.4. ⼀致性:只要A,B对象的状态没有改变,A.equals(B)必须始终返回true.5. A.equals(null) 要返回false.相信只要不是专业研究数学的⼈,都对上⾯的东西不来电.在实际应⽤中我们只需要按照⼀定的步骤重写equals()⽅法就可以了.为了说明⽅便,我们先定义⼀个程序员类(Coder):class Coder {private String name;private int age;// getters and setters}我们想要的是,如果2个程序员对象的name和age都是相同的,那么我们就认为这两个程序员是⼀个⼈.这时候我们就要重写其equals()⽅法.因为默认的equals()实际是判断两个引⽤是否指向内在中的同⼀个对象,相当于 == . 重写时要遵循以下三步:1. 判断是否等于⾃⾝.if(other == this)return true;2. 使⽤instanceof运算符判断 other 是否为Coder类型的对象.if(!(other instanceof Coder))return false;3. ⽐较Coder类中你⾃定义的数据域,name和age,⼀个都不能少.Coder o = (Coder)other;return .equals(name) && o.age == age;看到这有⼈可能会问,第3步中有⼀个强制转换,如果有⼈将⼀个Integer类的对象传到了这个equals中,那么会不会扔ClassCastException呢?这个担⼼其实是多余的.因为我们在第⼆步中已经进⾏了instanceof 的判断,如果other是⾮Coder对象,甚⾄other是个null, 那么在这⼀步中都会直接返回false, 从⽽后⾯的代码得不到执⾏的机会.上⾯的三步也是<Effective Java>中推荐的步骤,基本可保证万⽆⼀失.如何重写hashCode()⽅法在JavaSE 7 Specification中指出,"Note that it is generally necessary to override the hashCode method whenever this method(equals) is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes."如果你重写了equals()⽅法,那么⼀定要记得重写hashCode()⽅法.我们在⼤学计算机数据结构课程中都已经学过哈希表(hash table)了,hashCode()⽅法就是为哈希表服务的.当我们在使⽤形如HashMap, HashSet这样前⾯以Hash开头的集合类时,hashCode()就会被隐式调⽤以来创建哈希映射关系.稍后我们再对此进⾏说明.这⾥我们先重点关注⼀下hashCode()⽅法的写法.<Effective Java>中给出了⼀个能最⼤程度上避免哈希冲突的写法,但我个⼈认为对于⼀般的应⽤来说没有必要搞的这么⿇烦.如果你的应⽤中HashSet中需要存放上万上百万个对象时,那你应该严格遵循书中给定的⽅法.如果是写⼀个中⼩型的应⽤,那么下⾯的原则就已经⾜够使⽤了:要保证Coder对象中所有的成员都能在hashCode中得到体现.对于本例,我们可以这么写:@Overridepublic int hashCode() {int result = 17;result = result * 31 + name.hashCode();result = result * 31 + age;return result;}其中int result = 17你也可以改成20, 50等等都可以.看到这⾥我突然有些好奇,想看⼀下String类中的hashCode()⽅法是如何实现的.查⽂档知:"Returns a hash code for this string. The hash code for a String object is computed ass[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]using int arithmetic, where s[i] is the ith character of the string, n is the length of the string, and ^ indicates exponentiation. (The hash value of the empty string is zero.)"对每个字符的ASCII码计算n - 1次⽅然后再进⾏加和,可见Sun对hashCode的实现是很严谨的. 这样能最⼤程度避免2个不同的String会出现相同的hashCode的情况.重写equals()⽽不重写hashCode()的风险在Oracle的Hash Table实现中引⽤了bucket的概念.如下图所⽰:从上图中可以看出,带bucket的hash table⼤致相当于哈希表与链表的结合体.即在每个bucket上会挂⼀个链表,链表的每个结点都⽤来存放对象.Java通过hashCode()⽅法来确定某个对象应该位于哪个bucket中,然后在相应的链表中进⾏查找.在理想情况下,如果你的hashCode()⽅法写的⾜够健壮,那么每个bucket将会只有⼀个结点,这样就实现了查找操作的常量级的时间复杂度.即⽆论你的对象放在哪⽚内存中,我都可以通过hashCode()⽴刻定位到该区域,⽽不需要从头到尾进⾏遍历查找.这也是哈希表的最主要的应⽤.如:当我们调⽤HashSet的put(Object o)⽅法时,⾸先会根据o.hashCode()的返回值定位到相应的bucket中,如果该bucket中没有结点,则将 o 放到这⾥,如果已经有结点了, 则把 o 挂到链表末端.同理,当调⽤contains(Object o)时,Java会通过hashCode()的返回值定位到相应的bucket中,然后再在对应的链表中的结点依次调⽤equals()⽅法来判断结点中的对象是否是你想要的对象.下⾯我们通过⼀个例⼦来体会⼀下这个过程:我们先创建2个新的Coder对象:Coder c1 = new Coder("bruce", 10);Coder c2 = new Coder("bruce", 10);假定我们已经重写了Coder的equals()⽅法⽽没有重写hashCode()⽅法:@Overridepublic boolean equals(Object other) {System.out.println("equals method invoked!");if(other == this)return true;if(!(other instanceof Coder))return false;Coder o = (Coder)other;return .equals(name) && o.age == age;}然后我们构造⼀个HashSet,将c1对象放⼊到set中:Set<Coder> set = new HashSet<Coder>();set.add(c1);再执⾏:System.out.println(set.contains(c2));我们期望contains(c2)⽅法返回true, 但实际上它返回了false.c1和c2的name和age都是相同的,为什么我把c1放到HashSet中后,再调⽤contains(c2)却返回false呢?这就是hashCode()在作怪了.因为你没有重写hashCode()⽅法,所以HashSet在查找c2时,会在不同的bucket中查找.⽐如c1放到05这个bucket中了,在查找c2时却在06这个bucket中找,这样当然找不到了.因此,我们重写hashCode()的⽬的在于,在A.equals(B)返回true的情况下,A, B 的hashCode()要返回相同的值.我让hashCode()每次都返回⼀个固定的数⾏吗有⼈可能会这样重写:@Overridepublic int hashCode() {return 10;}如果这样的话,HashMap, HashSet等集合类就失去了其 "哈希的意义".⽤<Effective Java>中的话来说就是,哈希表退化成了链表.如果hashCode()每次都返回相同的数,那么所有的对象都会被放到同⼀个bucket中,每次执⾏查找操作都会遍历链表,这样就完全失去了哈希的作⽤.所以我们最好还是提供⼀个健壮的hashCode()为妙.总结以上就是本⽂关于重写hashCode()和equals()⽅法详细介绍的全部内容,希望对⼤家有所帮助。
java集合去重复元素的方法Java集合去除重复元素的方法有很多,可以根据实际的场景来选择不同的方法。
下面我们来介绍几种常用的去除重复元素的方法:一、使用HashSet集合HashSet是一种java集合,其内部实现是基于“散列表”结构,添加元素时,会自动去除重复元素,因此可以使用HashSet来进行去重复操作。
比如将一个ArrayList中重复元素去除,可以先将ArrayList转换成HashSet,然后再转换回来。
代码如下:List list = ...; //待去重复的list集合HashSet h = new HashSet(list);list.clear();list.addAll(h);二、重写HashCode重写HashCode代表类似的对象,即具有相同内容的对象会有相同的HashCode,那么可以先存放对象到HashMap,再将HashMap的元素添加到list中,这样就可以去除重复元素。
代码如下:List list = ...; //待去重复的list集合HashMap<Object, Object> map=new HashMap<Object,Object>(list.size());for(int i=0;i<list.size();i++){map.put(list.get(i),list.get(i));}list.clear();list.addAll(map.values());重写equals和hashCode方法不仅可以实现将重复元素存放到HashMap的同一个key的效果,而且这种方式比上面的方式更加高级,可以比较全面的比较两个对象。
例如Java 中的字符串比较,他们重写了equals和hashCode的方法,来确认字符串的内容是否相同,而不仅仅是比较引用地址是否相同。
要实现这个功能,需要自定义Java中的类,然后重写equals和hashCode方法,在equals方法中实现对内容的比较,而hashCode方法中实现加入equals方法内容的Hash算法实现,来检查哈希值是否一致,从而去除集合中的重复元素。
重写map中equals方法
介绍
在Java中,java.util.Map是一个非常重要的接口,用于表示键值对的集合。
Map
接口的实现类可以是HashMap、TreeMap等。
在使用Map时,我们可能需要对其
key进行比较判断是否相等,此时就需要用到equals方法。
equals方法是Object类中的一个方法,用于判断两个对象是否相等。
在Map中,equals方法的作用是判断两个key是否相等。
因为Map中的key是唯一的,所以
判断两个key是否相等非常重要。
在默认情况下,Map中的equals方法是通过比较key的内存地址来判断是否相等的。
但是在很多情况下,我们可能需要根据key的特定属性来判断是否相等。
这就需要我们重写Map中的equals方法,来满足我们的需求。
为什么需要重写equals方法
在默认情况下,Map中的equals方法是通过比较key的内存地址来判断是否相等的。
这样的比较方式在很多情况下是不满足我们的需求的。
假设我们有一个Person类,该类有name和age两个属性。
我们用Person作为
Map的key,如果我们希望判断两个Person对象是否相等的方式是根据name的相
等来判断,那么就需要重写Person类中的equals方法。
如果我们不重写equals方法,那么在使用Person作为Map的key时,两个name
相同但age不同的Person对象会被认为是相等的。
这显然是不符合我们的需求的。
因此,为了满足特定的需求,我们需要重写Map中的equals方法。
如何重写equals方法
重写equals方法的步骤如下:
1.在Person类中重写equals方法。
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Person person = (Person) obj;
return Objects.equals(name, );
}
在该方法中,我们首先判断两个对象是否是同一个对象,如果是则直接返回true。
接着判断传入的对象是否为空或者是否与当前对象的类不一致,如果是则返回false。
然后将传入的对象强制转换为Person类,并比较两个Person对象的name
属性是否相等,如果相等则返回true,否则返回false。
2.使用重写的equals方法在使用Person类作为Map的key时,就可以使用
重写后的equals方法来判断两个Person对象是否相等了。
Map<Person, Integer> map = new HashMap<>();
Person person1 = new Person("Tom", 20);
Person person2 = new Person("Tom", 25);
map.put(person1, 1);
System.out.println(map.get(person2)); // 输出1
在上述代码中,我们将person1作为Map的key存入,并且设置value为1。
然后
我们使用person2作为key来获取对应的value,由于person2的name属性与person1相同,所以可以正常获取到value为1。
equals方法的约定
在Java中,equals方法有一些约定,这些约定需要满足才能正确使用equals方法。
1.自反性:对于任意非空引用x,x.equals(x)应该返回true。
2.对称性:对于任意非空引用x和y,如果x.equals(y)返回true,则
y.equals(x)也应该返回true。
3.传递性:对于任意非空引用x、y和z,如果x.equals(y)返回true且
y.equals(z)返回true,则x.equals(z)也应该返回true。
4.一致性:对于任意非空引用x和y,如果x.equals(y)返回true或者false,
多次调用x.equals(y)应该返回相同的结果。
5.对于任意非空引用x,x.equals(null)返回false。
在重写equals方法时,需要满足这些约定,以保证equals方法的正确使用。
总结
重写Map中的equals方法是为了满足特定需求,比如根据对象的特定属性来判断
两个对象是否相等。
重写equals方法的步骤包括在类中重写equals方法和使用重写后的equals方法。
在重写equals方法时,需要满足equals方法的约定,以保证equals方法的正确
使用。
重写equals方法可以提高代码的灵活性和精确性,使得Map的使用更加符合我们
的需求。
通过合理地重写equals方法,我们可以在Map中根据特定属性来判断两个对象是
否相等,从而更好地满足我们的业务需求。