• JDK源码学习系列01----String


                                                     JDK源码学习系列01----String

    写在最前面:

          这是我JDK源码学习系列的第一篇博文,我知道源码学习这条路很难坚持,但是我始终相信,不积跬步无以至千里。当然啦,兴趣和方法可以让这条路变得很是happy。初步计划是每天早上晨会前看一个类的源码,因为还在实习初期,所以任务不是那么滴繁重,更何况,时间就像那个,挤挤总是有的嘛~~晚上回来写写博文,一是加深理解二来也加深记忆方便以后查阅。学习的步骤当然是先从自己已经用的非常熟练的类入手。

         期待这一路的繁花盛景,哈哈~~~


    java.lang.String

    public final class String
        implements java.io.Serializable, Comparable<String>, CharSequence
    String 是静态类,不可以被继承,可以被序列化,实现了Comparable接口

    1.成员变量

    private final char value[];
        private final char value[];
        private final int offset;//偏移量
        private final int count;
        private int hash; 
    String是以字符数组的形式实现的,变量定义为final,说明String一旦初始化后就不可变,这也是与StringBuffer的最大区别。

    2.构造函数

    3.常用方法

       1.char charAt(int index) 

        源码很简单,注意参数的判断,养成编程的好习惯,注意细节。

    public char charAt(int index) {
            if ((index < 0) || (index >= count)) {//养成好习惯,参数的判断!
                throw new StringIndexOutOfBoundsException(index);
            }
            return value[index + offset];
        }
      2.boolean equals(Object anObject)

       原本传入的参数是object型,惭愧自己平时连这个都没有注意,因为源码中已经对问题进行了处理。个人绝对源码中的while(n--!=0)以及if(v1[i++]!=v2[j++])写的很好啊,让总是for的我掩面而过啊~~学习源码的编程风格~

    public boolean equals(Object anObject) {
    	if (this == anObject) { 
    	    return true;
    	}
    	if (anObject instanceof String) {
    	    String anotherString = (String)anObject;//注意细节,向下转型
    	    int n = count;
    	    if (n == anotherString.count) {
    		char v1[] = value;
    		char v2[] = anotherString.value;
    		int i = offset;
    		int j = anotherString.offset;
    		while (n-- != 0) {//这里写得太精妙了!~~
    		    if (v1[i++] != v2[j++])//点32个赞~~
    			return false;
    		}
    		return true;
    	    }
    	}
    	return false;
        }
    

    3.boolean equalsIgnoreCase(String anotherString)

       此源码用于时刻提醒自己,能用 x>y?a:b解决的情况就坚决不要去写if else之类的!!

     public boolean equalsIgnoreCase(String anotherString) {
            return (this == anotherString) ? true :
                   (anotherString != null) && (anotherString.count == count) &&
    	       regionMatches(true, 0, anotherString, 0, count);
        }
    4.boolean startsWith(String prefix, int toffset)

      注意,第一个参数是String而不是char,哈哈,

    public boolean startsWith(String prefix, int toffset) {
    	char ta[] = value;
    	int to = offset + toffset;
    	char pa[] = prefix.value;
    	int po = prefix.offset;
    	int pc = prefix.count;
    	if ((toffset < 0) || (toffset > count - pc)) {//时刻记得参数的考虑
    	    return false;
    	}
    	while (--pc >= 0) {//风格和上面提到的一样~自己写时注意--pc和pc--,还要注意代表的是长度还是下标
    	    if (ta[to++] != pa[po++]) {
    	        return false;
    	    }
    	}
    	return true;
        }
    5.boolean endsWith(String suffix)

       这个方法写的简直是大爱啊~~~代码的重用思想也用的很好

    public boolean endsWith(String suffix) {
    	return startsWith(suffix, count - suffix.count);
        }
    6.String replace(char oldChar, char newChar)

       注意,replace参数是char,源码思路是找到第一个出现的oldChar,如果oldChar的下标小于len的下标,把oldChar前面的存到临时变量buf中,把oldChar后面的所有oldChar都变为newChar.

    public String replace(char oldChar, char newChar) {
    	if (oldChar != newChar) {
    	    int len = count;
    	    int i = -1;
    	    char[] val = value;  
    	    int off = offset;    
    
    	    while (++i < len) {//!!!学习源码编程风格
    		if (val[off + i] == oldChar) {
    		    break;
    		}
    	    }
    	    if (i < len) {
    		char buf[] = new char[len];
    		for (int j = 0 ; j < i ; j++) {
    		    buf[j] = val[off+j];
    		}
    		while (i < len) {//!!!!!!!!!!
    		    char c = val[off + i];
    		    buf[i] = (c == oldChar) ? newChar : c;
    		    i++;
    		}
    		return new String(0, len, buf);
    	    }
    	}
    	return this;
        }
    
    7.int compareTo(String anotherString)

    public int compareTo(String anotherString) {
    	int len1 = count;
    	int len2 = anotherString.count;
    	int n = Math.min(len1, len2);
    	char v1[] = value;
    	char v2[] = anotherString.value;
    	int i = offset;
    	int j = anotherString.offset;
    
    	if (i == j) {
    	    int k = i;
    	    int lim = n + i;
    	    while (k < lim) {
    		char c1 = v1[k];
    		char c2 = v2[k];
    		if (c1 != c2) {//一旦不等就reurn
    		    return c1 - c2;
    		}
    		k++;
    	    }
    	} else {
    	    while (n-- != 0) {//漂亮的代码
    		char c1 = v1[i++];
    		char c2 = v2[j++];
    		if (c1 != c2) {
    		    return c1 - c2;
    		}
    	    }
    	}
    	return len1 - len2;
        }

    8.int compareToIgnoreCase(String str)

         此方法采用的是自定义比较器来实现忽略字母大小的比较,比较器类CaseInsensitiveComparator实现了Comparator和Serializable接口。

    public int compareToIgnoreCase(String str) {
            return CASE_INSENSITIVE_ORDER.compare(this, str);
        }
     public static final Comparator<String> CASE_INSENSITIVE_ORDER
                                             = new CaseInsensitiveComparator();
        private static class CaseInsensitiveComparator
                             implements Comparator<String>, java.io.Serializable {
    	// use serialVersionUID from JDK 1.2.2 for interoperability
    	private static final long serialVersionUID = 8575799808933029326L;
    
            public int compare(String s1, String s2) {
                int n1=s1.length(), n2=s2.length();
                for (int i1=0, i2=0; i1<n1 && i2<n2; i1++, i2++) {
                    char c1 = s1.charAt(i1);
                    char c2 = s2.charAt(i2);
                    if (c1 != c2) {
                        c1 = Character.toUpperCase(c1);
                        c2 = Character.toUpperCase(c2);
                        if (c1 != c2) {
                            c1 = Character.toLowerCase(c1);
                            c2 = Character.toLowerCase(c2);
                            if (c1 != c2) {
                                return c1 - c2;
                            }
                        }
                    }
                }
                return n1 - n2;
            }
        }
    9.String valueOf(Object obj)

        将object转换为String,比obj+""和obj.toString()都好,因为从源码中可以看出,valueOf()很好的避免了空指针异常。

     public static String valueOf(Object obj) {
    	return (obj == null) ? "null" : obj.toString();
        }
    10.int lastIndexOf(String str, int fromIndex)

         对于子串的定位or匹配,若能匹配,返回匹配开始的第一个下标;若是匹配失败则返回-1.

    public int lastIndexOf(String str, int fromIndex) {
            return lastIndexOf(value, offset, count,
                               str.value, str.offset, str.count, fromIndex);
        }
    static int lastIndexOf(char[] source, int sourceOffset, int sourceCount,
                               char[] target, int targetOffset, int targetCount,
                               int fromIndex) {
            /*
    	 * Check arguments; return immediately where possible. For
    	 * consistency, don't check for null str.
    	 */
            int rightIndex = sourceCount - targetCount;
    	if (fromIndex < 0) {
    	    return -1;
    	}
    	if (fromIndex > rightIndex) {
    	    fromIndex = rightIndex;
    	}
    	/* Empty string always matches. */
    	if (targetCount == 0) {
    	    return fromIndex;
    	}
    
            int strLastIndex = targetOffset + targetCount - 1;
    	char strLastChar = target[strLastIndex];
    	int min = sourceOffset + targetCount - 1;
    	int i = min + fromIndex;
    
        startSearchForLastChar:
    	while (true) {
    	    while (i >= min && source[i] != strLastChar) {
    		i--;
    	    }
    	    if (i < min) {
    		return -1;
    	    }
    	    int j = i - 1;
    	    int start = j - (targetCount - 1);
    	    int k = strLastIndex - 1;
    
    	    while (j > start) {
    	        if (source[j--] != target[k--]) {
    		    i--;
    		    continue startSearchForLastChar;
    		}
    	    }
    	    return start - sourceOffset + 1;
    	}
        }
    11.boolean contains(CharSequence s)

         对于CharSequence,是一个接口,String实现了这个接口。其实这个方法传入的参数就是字符串,那为什么不直接以String作为参数呢,因为此处还可以是StringBuffer和StringBuilder等。此方法用于检查是否包含子串,作用上和indexOf类似,从源码可以看出,contains实际上就是调用了indexOf方法。

    public boolean contains(CharSequence s) {
            return indexOf(s.toString()) > -1;
        }







  • 相关阅读:
    求正整数N(N>1)的质因数的个数。
    手机键盘输入字母
    第二部分进度
    第一部分:地域维度标准化
    利用python解析地址经纬度
    输入任意4个字符(如:abcd), 并按反序输出(如:dcba)
    python-->微信支付
    python-图片流传输(url转换二维码)
    python-qrcode-二维码
    ajax和axios、fetch的区别
  • 原文地址:https://www.cnblogs.com/oversea201405/p/3766898.html
Copyright © 2020-2023  润新知