zoukankan      html  css  js  c++  java
  • String研究

    =======================String===================================

    String里的==和equals
    Java String “equals”就是比较字符串的内容,由于以上程序中的所有字符串内容都是“test”,所以用equals比较它们都会相等。但是你是否知道Java中基类Obejct的equals方法跟“==”方法其实是一致的呢?只不过是String类继承Object类后,重载了equal的方法,使得其成为了比较字符串中的内容。

    很好的理解了equals之后,现在让我们来研究一下“==”方法的扑朔迷离。
    “==”是Java中的运算符,它比较的内容是两个对象的指针,也就是实际对象的地址(程序员无法重载)。

    http://www.jb51.net/article/37899.htm

    String里的+
    String hello = "hello"; 
    String hel = "hel"; 
    String lo = "lo"; 
    System.out.println(hello == "hel" + "lo"); 
    System.out.println(hello == "hel" + lo);

    第一个加法连接时,+号两边都是常量字符串,java就会将两者拼起来后到String Pool里找与之相等(用equals)的字符串,若存在则将其地址返回;不存在则在String Pool里新建一个常量对象,其值等于拼接后的字符串,并将其地址返回。 
    第二个加法连接时,+号两边有一个是变量,此时,java会在堆里新建一个对象,其值是两字符串拼接后的值,此时返回的地址是堆中新对象的地址。

    http://unique5945.iteye.com/blog/177812

    创建字符串的方式很多,归纳起来有三类:
    其一,使用new关键字创建字符串,比如String s1 = new String("abc");
    其二,直接指定。比如String s2 = "abc";
    其三,使用串联生成新的字符串。比如String s3 = "ab" + "c";
    Cliff:
    其四,使用串联和变量生成新的字符串。比如String s1; String s3 = "ab" + s1;


    String对象的创建

    String对象的创建也很讲究,关键是要明白其原理。
    原理1:当使用任何方式来创建一个字符串对象s时,Java运行时(运行中JVM)会拿着这个X在String池中找是否存在内容相同的字符串对象,如果不存在,则在池中创建一个字符串s,否则,不在池中添加。

    原理2:Java中,只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。

    原理3:使用直接指定或者使用纯字符串串联("+")来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但绝不会在堆栈区再去创建该String对象。Cliff:但是涉及到变量的时候,仍然会创建一个新的堆字符串。

    原理4:使用包含变量的表达式或concat来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。


    另外,String的intern()方法是一个本地方法,定义为public native String intern(); intern()方法的价值在于让开发者能将注意力集中到String池上。当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。

    参考:
    http://zy19880423.iteye.com/blog/434118

    * Note that it is generally necessary to override the {@code hashCode} method whenever this method is overridden, so as to maintain the general contract for the {@code hashCode} method, which states that equal objects must have equal hash codes.

    需要注意的是,一般来说,如果重写了equals方法,都必须要重写hashcode方法,来确保具有相同引用的对象,能够具有同样的hashcode值。
    虽然这个不是强制性的,但是如果不能保证相同的引用对象,没有相同的hashcode,会对系统留下很大隐患。


    String类的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 类的hashcode 方法

    public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;
    
            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
    return h;
    }

    可以看到hashcode的计算公式为: s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
    因此,对于同一个String,得出的hashcode必然是一致的
    另外,对于空的字符串,hashcode的值是0


    小结
    1.字符串比较时用的什么方法,内部实现如何?
    使用equals方法,先比较引用是否相同,后比较内容是否一致.

    2.hashcode的作用,以及重写equal方法,为什么要重写hashcode方法?
    hashcode是系统用来快速检索对象而使用,
    equals方法是用来判断引用的对象是否一致,
    当引用对象一致时,必须要确保其hashcode也一致,因此需要重写hashcode方法来确保这个一致性
    (Cliff:如果两个对象通过覆盖equals而相等,但不重写HashCode,那么会导致两个相同的数据有不同的HashCode值,从而存储两遍。)

  • 相关阅读:
    题解 【洛谷】AT654
    题解【洛谷】CF134A
    jquery中select的应用
    Linq to xml 小例
    mongodb 使用场景和不使用场景
    一个面试题的解答-----从500(Id不连续)道试题库里随机抽取20道题!
    数据采集
    50款强力jquey,js 插件推荐
    node.js 学习
    wcf好文集合
  • 原文地址:https://www.cnblogs.com/findumars/p/3249437.html
Copyright © 2011-2022 走看看