赞
踩
我不想过庸庸碌碌、平平淡淡的一生,我这一生我想总该要做出一些成绩,以不至于到老闲暇时候回首过往满是后悔,不想到了父母爱人病倒需要钱的时候,满是无奈与自责,不想到了为人父母时老婆孩子有想买的礼物的时候,沉默不语无法满足;
目录
JAVA语言规范要求equals方法具有下面的特性:(非空对象)
“==”是运算符,如果等号两边是基本数据类型(八种基本数据类型),则比较的是存储的值;如果是引用数据类型,则比较的是所指向对象的地址值。
equals是Object类中的方法,所有java类都直接或者间接继承object类,它比较的是所指向的对象的地址值,一般情况下,重写之后才比较的是对象存储的值(。
- public boolean equals(Object obj) {
- return (this == obj);
- }
基本类型有八个:byte\ int\ double \float\ short\ long\ char \boolean
而引用类型,可以简单理解为就是对象(例如String、date类等)。
equals 方法不能用于比较基本数据类型,如果没有对 equals 方法进行重写,比较的是引用类型的变量所指向的对象的地址值:错误示例如下:
- int a=1;
- int b=1;
- System.out.println(a.equals(b));
- //不能运行,会直接报错,因为equals方法不能用于比较基本数据类型
一般情况下,类会重写equals方法用来比较两个对象的实体内容(即对象具体的值)是否相等。比如String类中的equals()是被重写了,比较的是对象的值。
对上面标黄色标记补充:(在黄色标记的地方,我们可能会想到我们为什么要去重写equals方法呢?因为equals方法时声明在超类object中的,所有Java类都继承了object类,呢么也就可以使用object类中的方法,在不重写的情况,我们调用equals方法,比较的是对象的地址值,此时的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;
- }
笔记:String类的底层其实是char数组。
总结 :“== ”对于基本类型来说是值比较,对于引用类型来说是比较的是地址值; 而 equals 默认情况下是引用比较,只是很多类重写了 equals 方法,比如 String、Integer 等,引用比较变成了值比较,所以在被重写的情况下 equals 比较的是值是否相等,通常我们自定义的Java类也是会这样重写的,使equals方法去比较两个对象的实体值是否相等。
- if (anObject instanceof String) {
- String anotherString = (String)anObject;
- int n = value.length;
原因:要将要比较的对象向下转换,这样才能访问子类的方法,才能比较子类的方法
instanceof 作用是:判断一个引用类型变量所指向的对象是否是一个类(或接口、抽象类、父类)的实例,即它左边的对象是否是它右边的类的实例,该运算符返回boolean类型的数据。
对象编程有两个重要的相等概念:值相等和引用相等。值相等的意思是它们的数据成员按内存位分别相等。引用相等则是指它们指向同一个内存地址。引用相等必然推出值相等,值相等却未必能推出引用相等。对于基本类型关系等号“==”判断两者是否值相等(结构类型和枚举类型没有定义关系等号“==”,我们必须自己定义)。对于引用类型关系等号“==”判断两者是否引用相等。
1.如果子类能够拥有自己的相等的概念,则对称性需求将强制采用getClass进行检测。
2.如果由父类决定相等的概念,那么就可以用instanceof进行检测,这样可以在不同子类的对象之间进行相等的比较。
1. 显示参数命名为otherObject,稍后需要将它转换成另一个叫做other的变量。
2. 检测this与otherObject是否引用同一个对象。 if(this == otherObject)
3. 检测otherObject是否为null,如果为 null ,返回 false。这项检测是很必要的。
4. 比较this与otherObject是否属于同一个类。如果equals的语义在每一个子类中有所改变,就使用getClass 检测 ——if(getClass() != otherObject.getClass()) return false;
如果所有子类都有相同的相等性语义,可以使用instanceof检测——if(otherObject instanceof ClassName) return false;
(instanceof 是Java的一个二元操作符(运算符),也是Java的保留关键字。它的作用是判断其左边对象是否为其右边类的实例(子类的对象也是父类的),返回的是boolean类型的数据。用它来判断某个对象是否是某个Class类的实例。
与之对应的是getClass方法:getClass()是object类中的方法,可返回Class类型的实例(返回对象所属的直接类),对其调用其他的方法,可以获得当前类的各种信息)
5. 将otherObject转换为相应的类类型变量。
ClassName other= (ClassName)otherObject
①为什么要进行强制类型转换?
答:要将要比较的对象向下转换,这样才能访问子类的方法,才能比较子类的方法
②子类对象被强制转换成父类之后,还能不能访问子类属性?
答:能
6. 开始对所需要比较的成员变量进行比较,使用 == 比较基本类型域,使用equal比较对象域。如果所有的域都匹配,就返回 true;否则返回 false 。
7. 如果子类中重新定义equals就要在其中包含调用super.equals().
- public boolean equals(Object obj) {
-
- if(this == obj) return true;
-
- if(obj == null) return false;
-
- if(this.getClass() != obj.getClass()) return false; //子类中equals方法
-
- if(!(obj instanceof Object)) return false; //父类中equals方法
-
- }
euals与hashCode的定义必须一致:如果x.equals(y) == true,那么x.hashCode() = y.hashCode();
在子类中定义equals方法时,首先要调用父类的equals方法,如果父类中的属性都相等,就需要比较子类中的属性
用instance of 的缺陷,比如说父类引用子类的对象,但是子类的对象拥有和父类某个对象相同的属性,如果没有考虑子类特有的信息,则instance of 就不怎么好。
如果子类能够拥有自己的相等的概念,那么对称性需求将强制采用getClass进行检测。如果父类决定相等的概念,那么就可以使用instanceof进行检测,这样就可以在不同的子类的对象之间进行相等比较。
区别就是getClass()限制了对象只能是同一个类,而instanceof却允许对象是同一个类或其子类。
Java中,为什么大家都说重写了equals方法都要进而重写Hashcode方法呢?
原因是以下两个:
(1)java的hashcode有一个通用的协定,即相等的对象必须具有相等的散列码(hashCode)。
如果不重写hashcode会违反这个协定。
(2)对于HashSet和HashMap这些基于散列值(hash)实现的类。HashMap的底层处理机制是以数组的方法保存放入的数据的(Node<K,V>[] table),其中的关键是数组下标的处理。数组的下标是根据传入的元素hashCode方法的返回值再和特定的值异或决定的。如果该数组位置上已经有放入的值了,且传入的键值相等则不处理,若不相等则覆盖原来的值,如果数组位置没有条目,则插入,并加入到相应的链表中。检查键是否存在也是根据hashCode值来确定的。所以如果不重写hashCode的话,可能导致HashSet、HashMap不能正常的运作
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。