String

final類,也就是無法被繼承, 底層實際是 final char[] value ,享元模式最經典的存在。 所以存在於常量池中,並且不可改變,所以是線程安全的。 (jdk8之後常量池取消) 。 存儲於常量池中, 可以直接用=賦值(java特殊處理), 賦值時先會去常量池查找,沒有則新建。 幾乎所有操作在底層都是將char[] 複製備份之後在進行操作,並最終new String 已保證常量性. 可能引發內存泄漏。

之前的java版本引發內存泄漏的著名方法就是 不斷new String的新對象,現在應該已經修復了此問題。

String : 

    StringBuffer : 線程安全的字符串變量,內容長度都可被修改,多個線程可以安全的訪問StringBuffer對象

    StringBuilder : 非線程安全的字符串變量,在單線程使用時,效率略高於StringBuffer,JDK 1.5之後加入

一些方法的源碼 :

// subString: 實際還是截取一段字符串,然後new 一個新的string
public String substring(int beginIndex) {
        if (beginIndex < 0) {//初始位置不能爲負
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        int subLen = value.length - beginIndex;//初始位置不能大於串長度
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
}

public String substring(int beginIndex, int endIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        if (endIndex > value.length) {//結尾位置不能大於串長度
            throw new StringIndexOutOfBoundsException(endIndex);
        }
        int subLen = endIndex - beginIndex;//結尾位置必須大於開始位置
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        return ((beginIndex == 0) && (endIndex == value.length)) ? this
                : new String(value, beginIndex, subLen);
 }

最著名的equals : 

 // equals: 判斷字符串相同
 public boolean equals(Object anObject) {
        if (this == anObject) { // 如果是自己 那肯定是一致的
            return true;
        }
        if (anObject instanceof String) { // 是否是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;
    }

忽略大小寫的equals :

equalsIgnoreCase:忽略大小寫
    public boolean equalsIgnoreCase(String anotherString) {
        return (this == anotherString) ? true
                : (anotherString != null)
                && (anotherString.value.length == value.length)
                && regionMatches(true, 0, anotherString, 0, value.length);
 }

 public boolean regionMatches(boolean ignoreCase, int toffset,
            String other, int ooffset, int len) { // 是否忽略大小寫,偏移量, 要比較的string,偏移量,要比較的長度
        char ta[] = value;
        int to = toffset;
        char pa[] = other.value;
        int po = ooffset;
      
        // 偏移量的驗證 
        if ((ooffset < 0) || (toffset < 0)
                || (toffset > (long)value.length - len)
                || (ooffset > (long)other.value.length - len)) {
            return false;
        }
        // 開始逐個對比
        while (len-- > 0) {
            char c1 = ta[to++];
            char c2 = pa[po++];
            if (c1 == c2) {
                continue;
            }
            if (ignoreCase) {//如果忽略大小寫
                char u1 = Character.toUpperCase(c1);//都變大寫在比較
                char u2 = Character.toUpperCase(c2);
                if (u1 == u2) {
                    continue;
                }
                if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
                    continue;//都變小寫在比較一次,多次判定
                }
            }
            return false;
        }
        return true;
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章