String的一點小東西

1. java中的hashCode 是什麼?

    hashCode()方法提供了對象的hashCode值,它與equals()一樣在Object類中提供,不過它是一個native方法,它的返回值默認與System.identityHashCode(object)一致,通常情況下,這個值是對象頭部的一部分二進制位組成的數字,這個數字具有一定的標識對象的意義存在,但絕對不等價於地址。
    在JDK7中,Hash相關的集合類對使用String作爲Key的情況,不再使用hashCode方式,而是有了一個hash31屬性,其餘類型保持不變。
    對比兩個對象的時候,即使他們的hashCode值相同,也不能說明這兩個對象時一樣的。

2. 編譯時優化和intern方法

class Test
{
    public static void main(String []args)
    {
        String a = "a";
        final String c = "a";
        String b = a +"b";
        String d = c +"b";
        String e = getA() + "b";
        String compare = "ab";
        System.out.println(b == compare);//false
        System.out.println(d == compare);//true
        System.out.println(e == compare);//false
    }
    public static String getA(){
        return "a";
    }
}

intern方法

public static void test(){
    String a = "a";
    String b = a + "b";
    String c = "ab";
    String d = new String(b);
    System.out.println(b == c);//F
    System.out.println(c == d);//F
    System.out.println(c == d.intern());//T
    System.out.println(d.intern() == b.intern());//T
}  
在HotSpotVM7及以前的版本中都是有Perm Gen(永久代)這個版塊的,在前面例子中所談到的String引用所指向的對象,他們存儲的空間正式這個版塊中的一個“常量池”區域,它對於同一個值的字符串保證全局唯一,當調用intern()方法時,JVM會在這個常量池中通過equals()方法查找是否存在等值的String,如果存在則直接返回常量池中這個String對象的地址;若沒有找到,則會創建等值的字符串(即等值的char[]數組字符創,但是char[]是新開闢的一份拷貝空間),然後再返回這個心創建空間的地址,只要是同樣的字符創,當調用intern方法時,都會得到常量池中對應String的引用,所以兩個字符串通過intern操作後用等號是可以匹配的,但是其俠侶並不高,輸在了對比地址之前要先找到地址上。  

3. String的“+” 操作

字符串在進行“+”連接時,實際上底部是進行的StringBuild.append()操作。
創建一個StringBuilder對象時,這個對象內部會分配16個長度的char數組,當發生append操作時,如果空間夠用,就繼續向後添加元素;若空間不夠,則會嘗試擴展空間。擴展空間的規則是:使用當前StringBuilder的count值 + 傳入字符串的長度   作爲新的char[]數組的參考值,這個參考值將會與StringBuilder的char[]數組中長度的2倍來取最大值,也就是說最少會擴展爲原來的2倍。
其中count值並不是char[]數組的總長度,而是當前StringBuilder中有效元素的個數,或者是通過StringBuilder.length()方法得到的值,char[]數組總長度可以通過capacity()方法獲取到。
首先確認一定,並不是String的“+”操作本身慢,而是大循環中大量的內存使得它的內存開銷變大了,導致了系統頻繁GC(在很多時候程序滿都是因爲GC多造成的),而且更多的是FULL GC ,效率纔會下降。
如果是 String str = a + b + c +d + e;只會申請一個StringBuilder進行多次append()操作,因爲這是一行代碼,或者是一條語句;

Buffer中的一些方法
 limit() 返回容量限制,區間大小爲[0-capacity]
flip() 將limit設置爲當前position的位置,將position設置爲0,將mark設置爲-1,這個動作的目的通常是爲了讀取Buffer中[0-position]中的所有數據
clear()用於清空緩衝區,僅將position設置0,limit設置爲與capacity同樣的大小,mark設置爲-1,數據還在,可以繼續從這裏面讀取數據,目的是爲了從新寫入數據。  

4. 其他

    當Integer 與 int 類型進行比較時,會將Integer轉化爲int類型來比較(也就是通過調用intValue()方法返回數字)Integer做比較的時候,Integer會自動拆箱,就是比較它的數字值。  
    Switch case 爲選擇語句,匹配時不會用equals(),而是直接使用“==” 而在switch case 語句中,語法層面case 部分是不能寫Integer對象的,只能是普通數字,在JDK7 中支持對String對象的switch case操作,在編譯後的字節碼文件中依然是if else語句,並且是通過equals比較的。
    在反射當中,對Integer屬性不能使用field.setInt()和fiels.getInt()操作。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章