请教高手一个非常基础但是很困惑的问题 本帖最后由 Velconia 于 2012-10-04 02:22:47 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 你看的是Object类的源码?你再去看看 String,Integer,java.awt.Dimension……等类的源码,找找它们的 equals() 看是怎么写的 要比较对象内容相等,要重写equals方法。这个问题,一般的书上都讲了。 支持1楼说的,例如String类的equals()就被重写过了,比较容易理解。 其实这个问题还是挺好解决的,只是要弄明白一个要点:== 是用于比较对象的引用,看它们的内在地址是否相同,而equals则是判断其中的值是否相等。知道这两点,真与假就很好判断了,当然,其中的情况还是挺多种的,容易让人误解。重写Object的equals方法,但根源还是如此。For example: String s1 = "java"; String s2 = "java"; String s3 = "j2se"; String s4 = new String("java"); 首先:s1 == s2; //返回true;(相信有些学java不久的会有疑惑,小弟在此多说两句,Stirng s2 = "java"与String s4 = new String("java")的差别在于,s2在产生之前,先找找看已经存在"java"没,存在的话,则直接指向其引用,而s4无论有或者没有"java"的存在,都会自己new一个出来。所以,s2与s1对象的引用是相等的). s1.equals(s2) true; s1 == s3 false; s1 == s4 false; s1.equals(s4) true; 注意一个比的是地址,一个指的是其中的值。 每个类都有自己的equals方法,覆盖继承自Object的equals 那是Object类中的写法,子类可以覆盖 object类的子类会复写的,楼主学习时不用太关注这些细节。代码写多了细节自然就懂了 给你解释下:equals方法是Object类提供的一个实例方法。正如你看到的源代码public boolean equals(Object obj) { return (this == ……这个和==运算符没有什么区别。 所有的类都直接或者间接继承了Object, 因此我们可以重写equals这个方法,希望自己来定义相等的标准,比如String, 它重写了equals方法:public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = count; if (n == anotherString.count) { char v1[] = value; char v2[] = anotherString.value; int i = offset; int j = anotherString.offset; while (n-- != 0) { if (v1[i++] != v2[j++]) return false; } return true; } } return false; }表示的是将此字符串与指定的对象比较。当且仅当该参数不为 null,并且是与此对象表示相同字符序列的 String 对象时,结果才为 true。 接着: 说equals方法时判断两个对象的值相等,是相当错误的说法。 只要你定义的类 重写了equals方法, 你就可以自己定义相等的标准。极端的如果这样写:可以和任何对象都相等ublic boolean equals(Object obj){ return true;} == 与equals 从比较概念上来说是不同的。==其实是一种基础类型数据比较实用的,对象之间的==是比较对象句柄的值是否相等(可以理解为类似内存地址值的比较),从这个意义上来说,也是一种基础类型值的比较。而equals是一种对象间比较(复杂类型的比较),但是java.lang.Object的equals实现内部是==是符合逻辑的,因为原生java.lang.Object对象之间,其实就是不同内存地址的object就认为是不同的对象。但是对于具体对象,如java.lang.String类型,它的相等逻辑是String对象中每个字符及其顺序的相同,所以String的equals实现被重写,用来逐一比对每个字符来实现equals,同样的例子,如java.lang.Integer类型,其相等依据是内部封装的int类型的值来决定的,因此equals要根据这个特性来重写(当然具体的比较过程可能更复杂)。因此,equals本身的比对特性是根据不同的具体实现类来实现的,而object类中的equals不具备参考性,但是其本身是符合逻辑的。相对于这个算法的实现,覆盖equals方法同样也有覆盖hashcode方法与tostring方法,在object类中hashcode是获得的equals用来作为比较依据的句柄值(object类中是个native方法,具体要看C语言部分),而tostring是打印句柄值。所以它们的实现也是与equals一致的,并且是符合逻辑的。但是它们同样没有具体实现类的参考价值。对于equals的实现有5大原则,具体可以查看《java核心技术》继承相关内容一章 看一下这个 http://blog.csdn.net/zhaoming262350/article/details/7910031http://blog.csdn.net/zhaoming262350/article/details/79100311.equals(Object obj)是Object类的一个方法,而Object是每个类的父类,因此所有的对象(包括数组)都能实现equals()方法,对于Object类的equals()方法等价于“==”;2.public boolean equals(Object obj)主要用于判断当前对象与obj对象是否 相等;3.equals()方法的特性:(对于任何引用非空的x和y,z)自反性:x.equals(x) 返回true;对成性:如果 x.equals(y) 返回true,则y.equals(x)也返回true;传递性:如果 x.equals(y),y.equals(z),则x.equals(z)也成立;一致性:只要x,y的引用值没有改变,那么对于多次调用x.equals(y),始终返回true或false;注意:对于x.equals(null) 终是false;4.在String类中用equals()方法,应该注意:String类中的equals()方法比较的是当前字符串与传进来字符串的值是否相等;String类的对象只能 用equals()方法判断,而不能用“=”;5.对于“==”;a:对于原生数据类型,比较的是两边的数值是否相等;b:对于引用类型的对象,比较的是两边的对象是否指向同一个对象或同一个地址。简单代码形式:public class StringTest1{ public static void main(String [] args) { String str1 = new String("zm");//equals()对于String 是比较字符串对象的内容 String str2 = new String("zm"); System.out.println(str1.equals(str2 ));//返回true String str3 = "aa";//直接给字符串赋值 String str4 = "bb"; System.out.println(str3.equals(str4 ));//返回false Object object = new Object(); Object object2 = new Object();//equals()比较Object引用类型变量的地址, System.out.println(object.equals(object2));// 返回false System.out.println(object.equals(object));//返回true String str5 = "hello"; //String str6 = "world"; String str7 = str5+"world"; String str8 = "helloworld"; System.out.println(str7==str8);//返回false System.out.println(str7.equals(str8));//返回true }}在hashSet中用equals()方法的比较值时,还要考虑hashCode()方法,hashCode()也是Object类的一个方法,此因任何Object类的子类也能继承和重写hashCode()方法;a:在一个程序执行的过程中,对于同一个对象的hashCode()多次调用,但是返回的值是相同的;b;对于两个对象来说,如果使用equals()方法比较返回true,那么这两个对象的hashCode值一定是相同的,因为这两个对象指向同一个地址;c:对于两个对象来说,如果使用equals()方法比较返回false,说明没有指向同一个地址,那么这两个对象的hashCode值不要求一定不同(可以相同,可以不同),但是如果不同则可以提高应用的性能;d:对于Object类来说,不同的Object对象的hashCode值是不同的(Object类的hashCode值表示的是对象的地址),这与哈希表以及函数有关。注意:在使用hashSet时肯定用到hashCode()方法,判断已在集合中的值与增加对象的hashCode()值是不是相同。如果值不同,直接加到集合当中,如果hashCode值相同,在进行equals()方法比较,如果equals()方法返回true,表示对象已经加入到集合中,就不会加进去,否则就会把这个对象加到集合中。 至少String类里的equals方法重写了。 求教java线程问题 请教一个基础问题!!!!! 如何实现类似于C里的int sort(int a[])的数组排序 Combobox选取值问题 怎样在一个窗口中调用另一个窗口 这个问题值20分 『新年礼物】-2003年全年程序员和csdn开发高手电子版下载 在jbuilder7.0下运行报错,请帮我解决一下!急用! 请问在JAVA中我用BigDecimal来计算百分比,百分比之和不等于100% java好让人伤心啊!竟然捕捉不好鼠标事件! myclipse8.5支持使用struts 2.1的包吗? 求助,谢谢!
你看的是Object类的源码?
你再去看看 String,Integer,java.awt.Dimension……
等类的源码,找找它们的 equals() 看是怎么写的
For example:
String s1 = "java";
String s2 = "java";
String s3 = "j2se";
String s4 = new String("java");
首先:s1 == s2; //返回true;(相信有些学java不久的会有疑惑,小弟在此多说两句,Stirng s2 = "java"与
String s4 = new String("java")的差别在于,s2在产生之前,先找找看已经存在"java"没,存在的话,则直接指向其引用,而s4无论有或者没有"java"的存在,都会自己new一个出来。所以,s2与s1对象的引用是相等的).
s1.equals(s2) true;
s1 == s3 false;
s1 == s4 false;
s1.equals(s4) true; 注意一个比的是地址,一个指的是其中的值。
public boolean equals(Object obj) {
return (this == ……
这个和==运算符没有什么区别。 所有的类都直接或者间接继承了Object, 因此我们可以重写equals这个方法,希望自己来定义相等的标准,比如String, 它重写了equals方法:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
表示的是将此字符串与指定的对象比较。当且仅当该参数不为 null,并且是与此对象表示相同字符序列的 String 对象时,结果才为 true。
只要你定义的类 重写了equals方法, 你就可以自己定义相等的标准。
极端的如果这样写:可以和任何对象都相等
ublic boolean equals(Object obj){
return true;
}
而equals是一种对象间比较(复杂类型的比较),但是java.lang.Object的equals实现内部是==是符合逻辑的,因为原生java.lang.Object对象之间,其实就是不同内存地址的object就认为是不同的对象。但是对于具体对象,如java.lang.String类型,它的相等逻辑是String对象中每个字符及其顺序的相同,所以String的equals实现被重写,用来逐一比对每个字符来实现equals,同样的例子,如java.lang.Integer类型,其相等依据是内部封装的int类型的值来决定的,因此equals要根据这个特性来重写(当然具体的比较过程可能更复杂)。因此,equals本身的比对特性是根据不同的具体实现类来实现的,而object类中的equals不具备参考性,但是其本身是符合逻辑的。
相对于这个算法的实现,覆盖equals方法同样也有覆盖hashcode方法与tostring方法,在object类中hashcode是获得的equals用来作为比较依据的句柄值(object类中是个native方法,具体要看C语言部分),而tostring是打印句柄值。所以它们的实现也是与equals一致的,并且是符合逻辑的。但是它们同样没有具体实现类的参考价值。
对于equals的实现有5大原则,具体可以查看《java核心技术》继承相关内容一章
http://blog.csdn.net/zhaoming262350/article/details/7910031http://blog.csdn.net/zhaoming262350/article/details/7910031
1.equals(Object obj)是Object类的一个方法,而Object是每个类的父类,因此所有的对象(包括数组)都能实现equals()方法,对于Object类的equals()方法等价于“==”;
2.public boolean equals(Object obj)主要用于判断当前对象与obj对象是否 相等;
3.equals()方法的特性:(对于任何引用非空的x和y,z)
自反性:x.equals(x) 返回true;
对成性:如果 x.equals(y) 返回true,则y.equals(x)也返回true;
传递性:如果 x.equals(y),y.equals(z),则x.equals(z)也成立;
一致性:只要x,y的引用值没有改变,那么对于多次调用x.equals(y),始终返回true或false;
注意:对于x.equals(null) 终是false;
4.在String类中用equals()方法,应该注意:
String类中的equals()方法比较的是当前字符串与传进来字符串的值是否相等;
String类的对象只能 用equals()方法判断,而不能用“=”;
5.对于“==”;
a:对于原生数据类型,比较的是两边的数值是否相等;
b:对于引用类型的对象,比较的是两边的对象是否指向同一个对象或同一个地址。
简单代码形式:
public class StringTest1
{
public static void main(String [] args)
{
String str1 = new String("zm");//equals()对于String 是比较字符串对象的内容
String str2 = new String("zm");
System.out.println(str1.equals(str2 ));//返回true
String str3 = "aa";//直接给字符串赋值
String str4 = "bb";
System.out.println(str3.equals(str4 ));//返回false
Object object = new Object();
Object object2 = new Object();//equals()比较Object引用类型变量的地址,
System.out.println(object.equals(object2));// 返回false
System.out.println(object.equals(object));//返回true
String str5 = "hello";
//String str6 = "world";
String str7 = str5+"world";
String str8 = "helloworld";
System.out.println(str7==str8);//返回false
System.out.println(str7.equals(str8));//返回true
}
}
在hashSet中用equals()方法的比较值时,还要考虑hashCode()方法,hashCode()也是Object类的一个方法,此因任何Object类的子类也能继承和重写hashCode()方法;
a:在一个程序执行的过程中,对于同一个对象的hashCode()多次调用,但是返回的值是相同的;
b;对于两个对象来说,如果使用equals()方法比较返回true,那么这两个对象的hashCode值一定是相同的,因为这两个对象指向同一个地址;
c:对于两个对象来说,如果使用equals()方法比较返回false,说明没有指向同一个地址,那么这两个对象的hashCode值不要求一定不同(可以相同,可以不同),但是如果不同则可以提高应用的性能;
d:对于Object类来说,不同的Object对象的hashCode值是不同的(Object类的hashCode值表示的是对象的地址),这与哈希表以及函数有关。
注意:在使用hashSet时肯定用到hashCode()方法,判断已在集合中的值与增加对象的hashCode()值是不是相同。如果值不同,直接加到集合当中,如果hashCode值相同,在进行equals()方法比较,如果equals()方法返回true,表示对象已经加入到集合中,就不会加进去,否则就会把这个对象加到集合中。