• Java String 的equals, == , hascode的区别


    1、equals 和 ==

    ==在java中是比较引用的,即在内存中的地址。而String的equals()是比较字符串的内容

    http://blog.csdn.net/barryhappy/article/details/6082823

    先看这几句代码

    1. String s1 = "String";  
    2. String s2 = "String";  
    3. System.out.println(s1 == s2 );  
    4. System.out.println(s1.equals(s2));  

    结果为:

    true

    true

    这个结果说明什么呢?

    ==在java中是比较引用的,即在内存中的地址。而String的equals()是比较字符串的内容。

    第二个true无可争议,因为s1和s2的内容显然 相同。

    第一个true呢?

    这说明s1和s2的地址相同,s1和s2的地址为什么会相同?

    查阅资料,发现 :

    String s1 = "String";

    这种方式,java首先会在缓冲区查找是否有"String"这个常量对象,有就直接将其地址赋给s1,没有就创建一个"String",然后将其赋给s1;然后        

    String s2 = "String";

    java同样会在缓冲区中查找"String",这次能查找到了,因为s1创建了一个"String",所以会将其地址赋给s2,如此,s1和s2便有了相同的地址。

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    OK。

    再看这一段代码

    1. String s3 = new String("String");  
    2. String s4 = new String("String");  
    3. System.out.println(s3 == s4);  
    4. System.out.println(s3.equals(s4));  

    结果为:

    false

    true

    第二个true同样无争议。

    第一个false说明s3和s4不是指向同一地址。

    查阅资料发现,

    String s3 = new String("String");会直接在内存中开辟一个空间存储一个"String",并讲引用赋给s3;

    同样 String s4 = new String("String");也会开辟一个空间,降低至给s4;

    所以s3和s4的地址不一样。

       即 

    System.out.println(s3 == s4); 会打印出false。

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/

    关于String的equals方法:

    这是直接从jdk源码复制的equals方法代码: 

    1.   public boolean equals(Object anObject) {  
    2. if (this == anObject) {  
    3.     return true;  
    4. }  
    5. if (anObject instanceof String) {  
    6.     String anotherString = (String)anObject;  
    7.     int n = count;  
    8.     if (n == anotherString.count) {  
    9.         char v1[] = value;  
    10.         char v2[] = anotherString.value;  
    11.         int i = offset;  
    12.         int j = anotherString.offset;  
    13.         while (n-- != 0) {  
    14.             if (v1[i++] != v2[j++])  
    15.                 return false;  
    16.         }  
    17.     return true;  
    18.     }  
    19. }  
    20. return false;  
    21.   }   

    java的String是用字符数组模拟的。

    从上面的代码可以看出String的equals()的工作原理——

    1、首先比较引用,如果引用相同,返回true;

    2、比较类型,如果不是比较的不是String对象,返回false;

    3、比较长度,字符串长度不等时,返回false;

    4、逐个字符比较两个字符串,遇到不一样的字符,返回false;

    5、到最后都一致,返回ture;

    2、hashcode

    在这里主要是讲==与hashCode()之间的区别。

        String str1 = "nihao" ;
        String str2 = "nihao" ;
        
        String str3 = new String("nihao");
        String str4 = new String("nihao");
        
        System.out.println("str1==str2: " + (str1==str2));    // true
        System.out.println("str1==str3: " + (str1==str3));    // false
        System.out.println("str3==str4: " + (str3==str4));   // false
        
        System.out.println("HashCode:" + str3.hashCode());  // HashCode:104818427
        System.out.println("HashCode:" + str4.hashCode());  // HashCode:104818427
        
        System.out.println(str3.hashCode() == str4.hashCode());  // true
        System.out.println(str3.equals(str4));  // true

    第一个true,是因为str1和str2是同一个变量,这个变量在变量池中。

    第一个false,是因为str1在变量池中,而str3在堆栈中,所以是不同。

    第二个false,通过new创建的String,是两个不同的对象。

    虽然str3和str4是两个不同的对象,但是其hashCode值是一样的,这就和hashCode()函数有关了,下面是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类中,value是该字符串被转换成数组后的对象。由于offset总是为0,所以h一开始就是0。于是只要value是一样的,所 以hashcode一定是一样的。于是可以肯定的说,==在判断对象时,其实是根据对象在堆栈中的地址判断对象是不是一样,而不是根据hashcode 值。

    2. http://java.chinaitlab.com/others/773414.html

    Java String中的HashCode和equal

        1. hashSet中比较是否重复的依据是a.hasCode()=b.hasCode() && a.equals(b)

        2. String的hashCode依据: 以依赖于char[i]的int值以和char[i]的排列序的算法计算出的。不依赖String的ref.

        3. String的equals依据: a==b || ( a.length=b.length && { a[i]=b[i] } )

        4. 只有用a==b时比校的才是比校的ref,也就是说这时才是比校是a与b是不是同一个对象

        5. 结论: 两个不同ref的String可能会被认为是集合中的同一个元素。

     3.http://hi.baidu.com/songdenggao/blog/item/a7336a607b930d47ebf8f8df.html

    关于String.hashCode 

     String.hashCode(),提供将任意长的字符串哈希成一个整数。

    在Java中,整型数是32位的,也就是说最多有2^32= 4294967296个整数,将任意一个字符串,经过hashCode计算之后,得到的整数应该在这4294967296数之中。那么,最多有 4294967297个不同的字符串作hashCode之后,肯定有两个结果是一样的(这个可以用鸽巢定理来解释,hehe)。

    下面的两组,其hashCode就相等了:
    http://pic.bandaonews.com/PicView.aspx?id=37219

    http://tech.163.com/05/0829/09/1SAIIRG8000915BD.html

    http://news.sina.com.cn/c/2005-06-08/10076113241s.shtml

    http://news.edw.com.cn/show.aspx?id=3490&cid=25

    当用到这样的方法来得到字符串的哈希值,并且此哈希值可能作为系统中的一个比较重要的参数的时候,应该充分考虑到哈希值可能重复的后果并做好一定的容错处理

  • 相关阅读:
    如何测量字符串的高度宽度 and 精确取得字符串的高度宽度
    ListBox删除多项选择项
    Configuring TCP/IP settings by WMI. 用WMI对象访问.设置IP配置
    .Net Jpeg编码器bug
    foreach与for的性能比较
    Linq 处理 List数据
    JS中的拖动之—— ondragstart,ondrag,ondragend , ondragenter , ondragover , ondragleave, ondrop 的区别
    url参数中有+、空格、=、%、&、#等特殊符号的问题解决
    判断一个字符串是否在另一个字符串中
    <span>居中
  • 原文地址:https://www.cnblogs.com/zihaowang/p/5019204.html
Copyright © 2020-2023  润新知