黑马程序员技术交流社区

标题: == 跟 equals 比较的具体是是什么? [打印本页]

作者: 微凉的暮色    时间: 2015-6-11 23:51
标题: == 跟 equals 比较的具体是是什么?
本帖最后由 微凉的暮色 于 2015-6-12 00:04 编辑

题目:== 跟 equals 比较的具体是是什么?具体用String来解释:
我知道:
equals 比较的是 具体内容,==比较的是内存地址
但只能明白 equals 的比较原理 ,至于==是怎么回事?
0、按通常说的 hashCode() 代表虚拟地址值,两个新对象完全不应该相等,但实际输出的值一样 ?
忽略了String 覆写hashCode();方法了。。。。。。。。。
1、通过getBytes(),转化为二进制,直接输出 结果不同,但输出数组内容确一样?
2、据说 == 比较的是引用值 ?这个值能输出么?有什么方式展现下?
  1.                 String str =new String("XYZ");
  2.                 String s = new String(str);
  3.                 String s2 = new String(str);        
  4.                 System.out.println(s.hashCode());
  5.                 System.out.println(s2.hashCode());
复制代码







作者: hakey    时间: 2015-6-11 23:51
标题: 居然在最后一页,顶一下,望采纳
本帖最后由 hakey 于 2015-7-4 02:09 编辑

hashcode() 方法,在object类中定义如下:
  public native int hashCode();
说明是一个本地方法,它的实现是根据本地机器相关的。当然我们可以在自己写的类中覆盖hashcode()方法,比如String、Integer、Double。。。。等等这些类都是覆盖了hashcode()方法的。例如在String类中定义的hashcode()方法如下:
    public int hashCode() {
int h = hash;
if (h == 0) {
    int off = offset;
    char val[] = value;
    int len = count;

            for (int i = 0; i < len; i++) {
                h = 31*h + val[off++];
            }
            hash = h;
        }
        return h;
}
解释一下这个程序(String的API中写到):
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
使用 int 算法,这里 s 是字符串的第 i 个字符,n 是字符串的长度,^ 表示求幂。(空字符串的哈希码为 0。)

3.这里我们首先要明白一个问题:
equals()相等的两个对象,hashcode()一定相等;
equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。换句话说,equals()方法不相等的两个对象,hashcode()有可能相等。(我的理解是由于哈希码在生成的时候产生冲突造成的)。
反过来:hashcode()不等,一定能推出equals()也不等;hashcode()相等,equals()可能相等,也可能不等。解释下第3点的使用范围,我的理解是在object、String等类中都能使用。在object类中,hashcode()方法是本地方法,返回的是对象的地址值,而object类中的equals()方法比较的也是两个对象的地址值,如果equals()相等,说明两个对象地址值也相等,当然hashcode()也就相等了;在String类中,equals()返回的是两个对象内容的比较,当两个对象内容相等时,
Hashcode()方法根据String类的重写(第2点里面已经分析了)代码的分析,也可知道hashcode()返回结果也会相等。以此类推,可以知道Integer、Double等封装类中经过重写的equals()和hashcode()方法也同样适合于这个原则。当然没有经过重写的类,在继承了object类的equals()和hashcode()方法后,也会遵守这个原则。

在String类中的重写了equals方法,实现的事内容的比较。      每new一个对象,就在对空间中开辟一个新的地址,所以s和s2进行“==”比较得到的是false因为他们指向的地址不同。至于hashcode根据上面的产生方法,因为s和s2的对应的值一样,所以产生的hashcode也是一样的。

楼主想要知道“==”两边比较的是什么如果是两个对象那就是两个对象的地址,此时s==s2为false。

如果是基本数据类型例如: String s="黑马"; String s2="黑马";s,s2为字符串常量,存放在java虚拟机为它分配的内存在常量池中。如果常量池中存在“黑马“,s,s2就会指向其内存地址。如果不存在Java虚拟机会为“黑马”分配一个地址.
所以,s==s2得到的是true。

看了很久,搜了很多东西,不知道能不能解决你的的疑惑,我自己也学到了不少。哈哈  多多交流,欢迎给出意见。
作者: VIP1108210117    时间: 2015-6-12 00:02
新人不太懂这些,看到类似帖子,望采纳:
"=="和equals方法究竟有什么区别?(转)
http://bbs.itheima.com/thread-194145-1-1.html
(出处: 黑马程序员IT技术论坛)

作者: 微凉的暮色    时间: 2015-6-12 00:03
VIP1108210117 发表于 2015-6-12 00:02
新人不太懂这些,看到类似帖子,望采纳:
"=="和equals方法究竟有什么区别?(转)
http://bbs.itheima.com/t ...

(⊙o⊙)…这个说的很笼统,没涉及我问的
作者: 海洋你好    时间: 2015-6-12 09:13
应该是等号比较是的是地址和内容,equals比较的只是内容
作者: world.net    时间: 2015-6-12 09:22
equals方法没有被重写时,与==作用是一样的,被重写时常用来比较对象内容。
作者: world.net    时间: 2015-6-12 09:24
另外当equals方法被重写时,通常也会重写hashcode方法
作者: 微凉的暮色    时间: 2015-6-12 10:22
海洋你好 发表于 2015-6-12 09:13
应该是等号比较是的是地址和内容,equals比较的只是内容

简单理解可以这么说。不过我想把他的比较内容取出来
作者: 微凉的暮色    时间: 2015-6-12 10:26
world.net 发表于 2015-6-12 09:22
equals方法没有被重写时,与==作用是一样的,被重写时常用来比较对象内容。 ...

:lol
我想要知道的是具体的比较内容(⊙o⊙)
==前后是什么?
作者: vilion    时间: 2015-6-12 12:38
通过getBytes(),转化为二进制,直接输出 结果不同是因为创建了新对象,对象的应用不同。但输出数组内容一样,我想说的是对象的拷贝
作者: wx_d9b6mRbI    时间: 2015-6-12 13:33
当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。 JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地址,但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。

作者: 微凉的暮色    时间: 2015-6-12 18:35
wx_d9b6mRbI 发表于 2015-6-12 13:33
当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们 ...

说的不错,不过不是我要的答案,
:L其实你说的这些,我知道:handshake
作者: 微凉的暮色    时间: 2015-6-12 18:36
vilion 发表于 2015-6-12 12:38
通过getBytes(),转化为二进制,直接输出 结果不同是因为创建了新对象,对象的应用不同。但输出数组内容一样 ...

我用String 测试,忽略会改hashcode()了
:lol 帖子没去改
作者: 微凉的暮色    时间: 2015-6-12 19:52
libin159 发表于 2015-6-12 18:40
==操作运算符是用来比较两个变量的值是否相等的,也是用来比较存储内存中储存的数值是否相同,比较两个基本 ...

:o这不会是复制的吧,看着好熟悉
其实我想输出==两边比较的东西
作者: storer    时间: 2015-6-12 21:29
==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符。       如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块内存(堆内存),变量也占用一块内存,例如Objet obj = new Object();变量obj是一个内存,new Object()是另一个内存,此时,变量obj所对应的内存中存储的数值就是对象占用的那块内存的首地址。对于指向对象类型的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。       equals方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。例如,对于下面的代码:       String a=new String("foo");       String b=new String("foo");       两条new语句创建了两个对象,然后用a,b这两个变量分别指向了其中一个对象,这是两个不同的对象,它们的首地址是不同的,即a和b中存储的数值是不相同的,所以,表达式a==b将返回false,而这两个对象中的内容是相同的,所以,表达式a.equals(b)将返回true。       在实际开发中,我们经常要比较传递进行来的字符串内容是否等,例如,String input = …;input.equals(“quit”),许多人稍不注意就使用==进行比较了,这是错误的,随便从网上找几个项目实战的教学视频看看,里面就有大量这样的错误。记住,字符串的比较基本上都是使用equals方法。       如果一个类没有自己定义equals方法,那么它将继承Object类的equals方法,Object类的equals方法的实现代码如下:       boolean equals(Object o){       return this==o;  }       这说明,如果一个类没有自己定义equals方法,它默认的equals方法(从Object 类继承的)就是使用==操作符,也是在比较两个变量指向的对象是否是同一对象,这时候使用equals和使用==会得到同样的结果,如果比较的是两个独立的对象则总返回false。如果你编写的类希望能够比较该类创建的两个实例对象的内容是否相同,那么你必须覆盖equals方法,由你自己写代码来决定在什么情况即可认为两个对象的内容是相同的。
作者: cyd1058    时间: 2015-6-12 22:09
围观大牛解答
作者: 逝....曾经    时间: 2015-6-12 22:26
什么意思,是想输出当他们作比较的时候,他们是以怎样的形式做比较的吗
作者: 大侠之剑    时间: 2015-6-12 22:35
再次学习了
作者: 微凉的暮色    时间: 2015-6-13 09:58
逝....曾经 发表于 2015-6-12 22:26
什么意思,是想输出当他们作比较的时候,他们是以怎样的形式做比较的吗

差不多,输出的是他们的引用值
作者: ym123456    时间: 2015-6-13 22:50
再来学习了
作者: kuangzeyu    时间: 2015-6-14 01:12
好好理解下面的代码,体会体会
String s1 = new String("hello");
                    String s2 = new String("hello");
                    System.out.println(s1==s2);
                    System.out.println(s1.equals(s2));

                    String s3 = new String("hello");
                    String s4 = "hello";
                    System.out.println(s3==s4);
                    System.out.println(s3.equals(s4));

                    String s5 = "hello";
                    String s6 = "hello";
                    System.out.println(s5==s6);
                    System.out.println(s5.equals(s6));
作者: JAVADing    时间: 2015-6-14 22:32
==比较的是内存地址值;
equals比较的是内存中的具体内容;
作者: wdd    时间: 2015-6-15 14:31
没看懂什么意思,来围观答案
作者: ma1234    时间: 2015-6-15 19:59
==比较最后的值  equlse比较的是地址  重写equlse就是比较最后的值
作者: iFmmer    时间: 2015-6-15 23:13
任何对象都会有equals方法,因为是从object类继承而来的。
你可以默认为objict类当中的equals方法就是==。
有些情况下自己写的类是需要重写equals方法的,修改后的equals方法会去比较双方的地址和真实的值。
所以从object类当中继承来的equals方法与==结果相同,自己重写的equals方法面对两个值相同但是地址不同的对象时也可以返回false。

不知道说的对不对,以上是我个人学习的结果。
作者: ice24    时间: 2015-6-15 23:44
equals属于Object的方法 ,比较的是引用类型的地址值,而String重写了equals方法,比较内容是否相等 ,直接打印数组,出现的就是地址值。你可以查看下源码Object的equals方法。谢谢。
作者: ITClody    时间: 2015-6-16 11:10
equal是方法,而==是条件表达式
作者: 十里坡    时间: 2015-6-16 11:59
(转)==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符。
如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块内存(堆内存),变量也占用一块内存,例如Objet obj = new Object();变量obj是一个内存,new Object()是另一个内存,此时,变量obj所对应的内存中存储的数值就是对象占用的那块内存的首地址。对于指向对象类型的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。
equals方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。例如,对于下面的代码:
String a =new String("foo");
String b=new String("foo");
两条new语句创建了两个对象,然后用a,b这两个变量分别指向了其中一个对象,这是两个不同的对象,它们的首地址是不同的,即a和b中存储的数值是不相同的,所以,表达式a==b将返回false,而这两个对象中的内容是相同的,所以,表达式a.equals(b)将返回true。
在实际开发中,我们经常要比较传递进行来的字符串内容是否等,例如,String input = …;input.equals(“quit”),许多人稍不注意就使用==进行比较了,这是错误的,随便从网上找几个项目实战的教学视频看看,里面就有大量这样的错误。记住,字符串的比较基本上都是使用equals方法。
如果一个类没有自己定义equals方法,那么它将继承Object类的equals方法,Object类的equals方法的实现代码如下:
boolean equals(Object o){
return this==o;
}

这说明,如果一个类没有自己定义equals方法,它默认的equals方法(从Object类继承的)就是使用==操作符,也是在比较两个变量指向的对象是否是同一对象,这时候使用equals和使用==会得到同样的结果,如果比较的是两个独立的对象则总返回false。如果你编写的类希望能够比较该类创建的两个实例对象的内容是否相同,那么你必须覆盖equals方法,由你自己写代码来决定在什么情况即可认为两个对象的内容是相同的。
作者: 严晗哲    时间: 2015-6-16 17:31
==:在比较引用型变量时,比较的是内存地址值。equals:是Object下的方法,当没有重写时,比较的也是地址.
具体到String类下,String他写了equals方法,比较的具体的字符串是否相同。
代码体现:
String s1 = new String("abc");//创建对象s1
String s2 = new String("abc"); //创建对象s2
System.out.println(s1 = = s2);//这时输出的结果为false,通过==比较的是两个对象的内存地址值。
System.out.println(s1.equals(s2));//结果为true,比较的是具体的两个字符串。

注意:
当没有创建对象直接指向字符串常量时,==由于指向的是常量池地址,所以他们是相等的。
String s3 = "abc";
String s4 = "abc";
System.out.ptintln(s3 == s4 ); \\结果为true,由于字符串时常量,这时s3、s4同时指向了字符串常量池中的"abc"常量,所以地址值相同.


hashCode()方法,返回的是一个虚拟的内存地址值,可以通过比较哈希值来判断是否是同一个对象。






作者: d18819042875    时间: 2015-6-16 21:57
直接跟你说吧,equals是Object类下的子类,如果Equals被重写了就是比较内容,如果没被重写就是比较地址值,==号一般是比较内容,但是这个例子你需要好好理解
String s1="你好";
String s2=“吗”;
Strings3=“你好吗”;
System.out.println(s3==“|你好”+"吗");结果是true
System.out.println(s3==s1+s2)结果是false
原因是,前者在编译的时候结果已经出来了
后者判断的话先要在常量池开辟空间,然后赋值到堆内存,所以结果为false
作者: vivante    时间: 2015-6-16 23:23
贴个源码加注释
/**这是String的成员equals方法的定义*/
public boolean equals(Object anObject) {
    //首先判断两个String引用是不是同一个对象
//this代表是调用对象的引用(地址),anObject是被比较对象的引用(地址)
//如果两个地址都相同,即是同一个对象,不用比较。当然返回true
        if (this == anObject) {
            return true;
        }
//如果对象是String类型的一个实例,则执行if内的操作
        if (anObject instanceof String) {
            String anotherString = (String) anObject;
            int n = value.length;
//如果两个字符串的长度不相等,不再比较,返回false
//相等就进入if继续判断
            if (n == anotherString.value.length) {
//把String类型的字符串,转换成底层的char类型的数组来判断
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
               //对两个string类型的转化后的char类型数组中的每个元素逐个比较,都相等即返回true。如遇到不相等的元素就返回fals
                while (n-- != 0) {
                    if (v1 != v2)
                            return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

总之,equals比较的是String中的每个字符的ascii码值是否相等,只要有不相等的就返回false。以上是个人见解,可能有描述不太得当的地方,仅为了好理解,纯手打。

作者: 逝....曾经    时间: 2015-6-17 14:54
微凉的暮色 发表于 2015-6-13 09:58
差不多,输出的是他们的引用值

你可以看下底层代码,==是比的一次引用值,equals比的是对象里的内容
作者: lucien_he    时间: 2015-6-17 15:37
== 和 Equals 的区别
  1. == 是一个运算符。
  2.Equals则是string对象的方法,可以.(点)出来。
  
  我们比较无非就是这两种 1、基本数据类型比较 2、引用对象比较
  1、基本数据类型比较
  ==和Equals都比较两个值是否相等。相等为true 否则为false;
  
  2、引用对象比较
  ==和Equals都是比较栈内存中的地址是否相等 。相等为true 否则为false;
  
  需注意几点:
  1、string是一个特殊的引用类型。对于两个字符串的比较,不管是 == 和 Equals 这两者比较的都是字符串是否相同;
  2、当你创建两个string对象时,内存中的地址是不相同的,你可以赋相同的值。
  所以字符串的内容相同。引用地址不一定相同,(相同内容的对象地址不一定相同),但反过来却是肯定的;
  3、基本数据类型比较(string 除外) == 和 Equals 两者都是比较值;
作者: 825176857    时间: 2015-6-17 16:00
楼上的都答非所问。
0、HashCode不是内存地址,是根据排列算出来的一个值,hashCode是指对象的散列码,具体值是由对象的hashCode()方法返回的值,但绝不是内存地址,你甚至可以重写该方法让每个对象的hashCode都一样。
1、
  1. String str =new String("XYZ");
  2. str.getBytes();
复制代码

一个对象用getBytes()多运行几遍发现得到的值也会不同。
getBytes()得到的是一个byte的数组对吧。你要看得到的byte应该遍历打印这个byte数组里的元素,而不是直接打印byte对象。
  1.                 byte[] by = str.getBytes();
  2.                  for(int i=0;i<by.length;i++)  {
  3.                      System.out.println(by[i]);
  4.                  }
复制代码

这样就相同了
2、如果一个值是引用类型的,那么它的存储空间将从堆中分配.由于引用值的大小会改变,所以不能把它放在栈中,
则放入堆中,而堆中的内存地址是变化的无法得到。
希望解决你的问题。
作者: 微凉的暮色    时间: 2015-6-17 16:35
825176857 发表于 2015-6-17 16:00
楼上的都答非所问。
0、HashCode不是内存地址,是根据排列算出来的一个值,hashCode是指对象的散列码,具体 ...

:o
能把第二点仔细说下么?

作者: 逝....曾经    时间: 2015-6-17 17:26
微凉的暮色 发表于 2015-6-13 09:58
差不多,输出的是他们的引用值

应该得重写toString才能看到他们的引用值,不重写看到的只能是他们的内容,或许你可以用其他类型的试试,不用String类型
作者: 微凉的暮色    时间: 2015-6-17 17:49
逝....曾经 发表于 2015-6-17 17:26
应该得重写toString才能看到他们的引用值,不重写看到的只能是他们的内容,或许你可以用其他类型的试试, ...

重写,我只能返回hashCode(), 要输出两边的比较内容,API里没找到方法
而且都说,java 不能返回地址值
正在等待楼上的楼上 详解这个地址的问题
作者: 逝....曾经    时间: 2015-6-17 18:38
微凉的暮色 发表于 2015-6-17 17:49
重写,我只能返回hashCode(), 要输出两边的比较内容,API里没找到方法
而且都说,java 不能返回地址值
正 ...

你试试这个;自己定义一个类,然后再创建实例。多创建几个实例再比较一下
试试
作者: 825176857    时间: 2015-6-17 18:47
微凉的暮色 发表于 2015-6-17 16:35
能把第二点仔细说下么?

String str=“XYZ”;
         str=“str”;
变量str是在栈内存中的 他开始存的是堆内存中“XYZ”的字符串的内存地址变为“str”字符串的内存地址。至于“XYZ” “str”的内存地址是多少,没办法知道的。因为在程序运行过程中,每创建一个对象都会被分配一定的内存用以存储对象数据。如果只是不停的分配内存,那么程序迟早面临内存不足的问题。所以在有一个内存回收机制来释放过期对象的内存,以保证内存能够被重复利用。
作者: 342508558    时间: 2015-6-18 15:37
==比较两个变量引用的对象是否相等,即变量指向的内存地址是否相等。
equals的比较逻辑每个类都不一样,String的equals是遍历String 的每一个字符是否相等。
objetct 的 hashcode 返回该对象的内存地址,
Object:
public native int hashCode(); 所以是用jni获得滴
public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
        Object o1 = new Object();
                Object o2 = new Object();
                System.out.println(o1);
                System.out.println(o2);
java.lang.Object@15db9742
java.lang.Object@6d06d69c
地址就是那串数字
String 重写了hashcode,所以拿不到地址。
我没遇到过获得对象内存地址的API。
作者: 王冲6060    时间: 2015-6-18 19:57
学习了!
作者: 洪伟    时间: 2015-6-18 22:08
== 如果想返回true 的话,两个比较者必须是同一个对象。如果比较者之间没有任何继承关系的话,就不会通过编译。其他我就不知道了
作者: 洪伟    时间: 2015-6-18 22:19
我所值的 必须是同一个对象 是说  == 符号两边的引用必须指向堆内存中同一对象 或者说是地址。  楼主可以自定义一个类,声明3个实例,比如  person  a,b,c  。然后将a = new person(15) b= new person(15)  然后 将 a赋给c   即  c = a  然后  打印  a==b  a==c  的值  应该一个是false  一个是 true
在打印 a  b  c  (System.out.println(a);System.out.println(b);System.out.println(c);)a 和c  应该是一样
这就证明了  ==   在比较 引用类型时只是比较 引用的地址时候相同,就和 比较两个整数值是一样的。  

声明:这是我认为的,不是官方啊。如果不对,恢复我一下哈
作者: 15383016390    时间: 2015-6-18 22:56
本帖最后由 15383016390 于 2015-6-18 23:16 编辑

1、对于基本数据类型“==”和equals都是比较值。2、对于引用对象,都是比较两者在栈内存中地址是否相同。
3、对于 String类型equals 比较的是 具体内容,==比较的是内存地址。
public class StringDemo{
       public static void main(String[] args){
            String s1 = "abc";
            String s2 = "abc";
            System.out.println(s1 == s2);
      }
}
运行结果是true,因为 字符串创建的时候,有一个字符串常量池,s1创建后,"abc"放入其中。s2创建的时候,"abc"已经存在于字符串常量池中,故引用变量s2直接指向了已经存在的"abc"字符串对象,故s1==s2。
public class StringDemo{
       public static void main(String[] args){
            String s1 = "abc";
            String s2 = new String("abc" );
            System.out.println(s1 == s2);
      }
}
这段代码运行结果是false,因为s1创建后,是在字符串常量池中创建了一个"abc"字符串对象。而s2是在堆内存中创建了另外一个"abc"字符串对象。两者在栈内存中的地址是不一样的。
把上面两例中的“==”都用equals替换,输出结果都是true。



作者: 远上寒山    时间: 2015-6-18 23:06
最浅显的就是==比较的是基本数据类型的值,equals比较的是引用数据类型的内容,equals是Object类中的一个方法,具体到每个类中的话是需要重写这个方法才能实现我们想要的结果。如果不重写该方法,默认比较的是引用数据的地址值。
作者: 行意天下    时间: 2015-6-19 06:34
看看源码就明白怎么回事了,==底层比较的是内存地址,也就是哈希值。equals,对于Object来说,equals调用的还是==,但是如果是其它类,如String等,会复写Object类equals方法,从而比较只是字符串的内容。不同类的equals方法功能内容可能都有可能不一致。
作者: dba_hotmail    时间: 2015-6-19 15:55
楼上已有人回答,equls是比较内容,==是比较内存地址
作者: JRT    时间: 2015-6-19 19:45
不就是地址值吗,不过String类重写了Object类中的equals()而已
作者: JRT    时间: 2015-6-19 19:46
wx_d9b6mRbI 发表于 2015-6-12 13:33
当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们 ...

受教,女中豪杰哦
作者: Diors    时间: 2015-6-19 20:39
你的这个例子里,三个字符串都是用new String初始化的,所以地址都不一样,用==比较结果都是false。但是内容一样,都是XYZ,用equals比较都是true。==比较地址,equals比较内容看具体的类中equals是怎么写的。
作者: kalon    时间: 2015-6-20 11:41
对于字符串变量来说,==比较的是值,而equals比较的是其内容
作者: g552092947    时间: 2015-6-20 16:46
当new了对象之后,对象放在了堆中,而内容放在了栈里边,== 是先比较堆的地址,如果地址对,在比较栈中的内容。equals是比较栈中的内容。   
作者: bowen-xiao    时间: 2015-6-21 08:51
本帖最后由 bowen-xiao 于 2015-6-21 08:54 编辑
wx_d9b6mRbI 发表于 2015-6-12 13:33
当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们 ...
  1. String s1 = new String("123");
  2.                 String s2 = new String("123");
  3.                
  4.                 System.out.println(s1 == s2);//
复制代码


猜猜什么结果
作者: 金大少    时间: 2015-6-21 15:11
       值类型是存储在内存中的栈,而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。
       ==操作比较的是两个变量的值是否相等,
       对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。        
        equals操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。
        ==比较的是2个对象的地址,而equals比较的是2个对象的内容。显然,当equals为true时,==不一定为true。
         


作者: 金大少    时间: 2015-6-21 15:12
       值类型是存储在内存中的栈,而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。==操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同 。equals操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。==比较的是2个对象的地址,而equals比较的是2个对象的内容。显然,当equals为true时,==不一定为true。
         


作者: guohaichang    时间: 2015-6-21 23:26
最精确的说:“==”比较的是变量值,“equals()”比较的是对象内容。阐述一下,8个基本类型,用==比较不必说,就是比较变量值;对象引用类型,比较时也是比较的引用变量值,何为引用变量呢,这就是实现机制问题了,引用本身也是一个变量,其值就是该对象的存储地址。而equals(),比较的是变量实际表示的值,那么基本类型不必说,对象引用类型实际表示的值是对象内部成员的值,而不是引用变量的值。区别就在这,二者有交叉,有区别。
作者: guohaichang    时间: 2015-6-21 23:28
实际上,“==”,从实现原理上来说,这个比较是计算机认为的相等,而equals()比较的是人认为的相等。
作者: 丁铭检    时间: 2015-6-22 12:34
==:是比较它们的内存空间是不是相同的,而

equals:是比较它们的值
作者: 君子无醉    时间: 2015-6-22 21:09
楼主说的这个问题我重点研究过 ==比较的是值是否相等,如果比较的是基本类型,那么就会比较这两个值,比如3==2,返回值是false  如果比较的是引用类型,比如两个学生对象,那么比较的是地址值,这个地址值就是栈内存变量指向堆内存空间的地址值,你可以造一个没有重写toString()方法的对象,用println输出一下对象名来看一下这个地址值。。
equal()是一个方法,它存在于Object这个类中,又因为这个类是所有类的父类,所以所有对象都可以调用这个方法,而且这个方法的参数接受的也是任意类型对象  这个方法在Object中,代码大致是return this==obj,就是默认返回的结果是比较这两个对象的地址值是否相同,如果你想要让这个方法比较的是对象的内容是否相同(比如一个学生类  比较姓名 年龄等等),那你自己就需要重写,根据你的需求来重写具体要比较什么,然后设置返回值是true还是false。。至于怎么重写,你可以用eclipse自动生成开看一下 或者你可以通过API查看String这个类,然后看看它里面的equal方法。。这个方法就是重写后的(java工作人员,封装这个类的时候 重写的)  还有一个需要注意的地方,ArrayList集合中的contains这个方法,底层依赖的是equal方法,如果你集合中的对象中 没有重写equal方法,那么比较是否包含的结果永远都会返回fslse。哥们,纯手打,希望给点分  如果还有不懂的可以加我扣扣  363246266

作者: jin3254576    时间: 2015-6-22 21:43
我学了半个月的理解就是  ==是用于基本类型的比较 而equals比较的是 引用类型里面的内容。
作者: wgy    时间: 2015-6-23 07:37
我认为应该是比较两个变量的值是否相等,其中包括数值型变量和引用类型变量。:):)
作者: 陌上桑    时间: 2015-6-23 11:00
这是put()  方法的源码:
public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key.hashCode());
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }

    先调用hashCode方法得到该元素的hashCode值,然后查看table中是否存在该hashCode值,如果存在则调用equals方法重新确定是否存在该元素
Hashcode()  地址代表一个域,与对象是一对多的关系,,,判断hashcode后,再判断内容的方式,以会提高效率。
    具体hashcode()产生方式,可以参考源码。  不过不在object    hashcode() 是native类型,用c/c++写成的  
作者: 黑马无敌    时间: 2015-6-23 15:08
楼上正解
作者: 段培峰    时间: 2015-6-23 22:13
this.name == s.name; //比较2个人的名字是否相等,因为name是String类型,String是一个类,所以这个式子可以写成this.name.toString() == s.name.toString();    toString()是对象后面默认加的的,只是省略不写了,例如System.out.print(s.toString)一般写为System.out.print(s);  然而toString()在String中被重写了,重写之后变成输出String的内容了。其他没有重写的类任然是输出地址值。所以可以在比较内容的时候要用equals。如this.name.equals(s.name)。总结,基本类型数据比较用==,引用类型的比较用equals
作者: czf小耗子    时间: 2015-6-26 19:33
围观下。菜鸟还没学习到这个地方
作者: fantianfei    时间: 2015-6-27 08:39
10楼正解
作者: 德艺双馨    时间: 2015-6-28 23:36
==如果比较的是基本类型,那比较的是值是否相等,如果比较的是引用类型,那比较的就是内存地址是否一样
equals是Object根类的一个方法,该方法如果没有被重写,那么比较的就是hashCode()虚拟地址是否相同,比如你自己定义一个学生类,如果你的学生类没有重写equals()方法,那么比较的就是这两个学生对象的地址是否相同,如果你重写了该方法,那就按你重写的规则做比较。String类(继承了Object根类)是重写了equals()方法的,重写后equals()方法是按内容是否相同返回布尔类型值。
作者: hakey    时间: 2015-7-4 02:10
楼主似乎已经不再关心此问题了哈,希望你可以看看我的,因为确实花了很长时间解决的。
作者: 张恩祺    时间: 2015-7-5 23:45
比较的就是父类的属性.
作者: 微凉的暮色    时间: 2015-7-6 09:02
hakey 发表于 2015-7-3 20:39
hashcode() 方法,在object类中定义如下:
  public native int hashCode();
说明是一个本地方法,它的实 ...

可能是我问的 问题不太明确,其实我想的是把 equals两边的东西输出到控制台,不过由于JAVA的特性,这个问题没法输出
回头 我按照你的试试去
作者: hakey    时间: 2015-7-6 10:44
微凉的暮色 发表于 2015-7-6 09:02
可能是我问的 问题不太明确,其实我想的是把 equals两边的东西输出到控制台,不过由于JAVA的特性,这个问 ...

是的,你甚至都得不到,所以不能输出的。恩,好的,你试试吧
作者: 李文思    时间: 2015-7-13 09:01
视频上的老师是说,==比较的是地址值,就是引用,
在Object以及它的子类上,如果没有覆写equals方法的话,比较的也是引用,
我们可以覆写equals方法,用来比较我们指定的内容。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2