读String源码
程序员文章站
2022-03-19 11:34:51
...
//先看构造函数 public String() { this.value = new char[0]; } public String(String original) { this.value = original.value; this.hash = original.hash; } public String(char value[]) { this.value = Arrays.copyOf(value, value.length); } //从offset位置开始复制count个char元素 public String(char value[], int offset, int count) { if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } if (count < 0) { throw new StringIndexOutOfBoundsException(count); } // Note: offset or count might be near -1>>>1. //如果数组不够长 if (offset > value.length - count) { throw new StringIndexOutOfBoundsException(offset + count); } this.value = Arrays.copyOfRange(value, offset, offset+count); } public String(int[] codePoints, int offset, int count) { if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } if (count < 0) { throw new StringIndexOutOfBoundsException(count); } //如果超界了 if (offset > codePoints.length - count) { throw new StringIndexOutOfBoundsException(offset + count); } final int end = offset + count; int n = count; for (int i = offset; i < end; i++) { int c = codePoints[i]; //确定是否在BMP代码点 if (Character.isBmpCodePoint(c)) continue; //确定是否是有效的Unicode代码点 else if (Character.isValidCodePoint(c)) n++; else throw new IllegalArgumentException(Integer.toString(c)); } final char[] v = new char[n]; for (int i = offset, j = 0; i < end; i++, j++) { int c = codePoints[i]; if (Character.isBmpCodePoint(c)) v[j] = (char)c; else Character.toSurrogates(c, v, j++); } this.value = v; } public String(byte bytes[], int offset, int length, String charsetName) throws UnsupportedEncodingException { if (charsetName == null) throw new NullPointerException("charsetName"); checkBounds(bytes, offset, length); this.value = StringCoding.decode(charsetName, bytes, offset, length); } //检查是否超出界限 private static void checkBounds(byte[] bytes, int offset, int length) { if (length < 0) throw new StringIndexOutOfBoundsException(length); if (offset < 0) throw new StringIndexOutOfBoundsException(offset); if (offset > bytes.length - length) throw new StringIndexOutOfBoundsException(offset + length); } static char[] decode(String charsetName, byte[] ba, int off, int len) throws UnsupportedEncodingException { StringDecoder sd = deref(decoder); String csn = (charsetName == null) ? "ISO-8859-1" : charsetName; if ((sd == null) || !(csn.equals(sd.requestedCharsetName()) || csn.equals(sd.charsetName()))) { sd = null; try { Charset cs = lookupCharset(csn); if (cs != null) sd = new StringDecoder(cs, csn); } catch (IllegalCharsetNameException x) {} if (sd == null) throw new UnsupportedEncodingException(csn); set(decoder, sd); } return sd.decode(ba, off, len); } public String(byte bytes[], int offset, int length, Charset charset) { if (charset == null) throw new NullPointerException("charset"); checkBounds(bytes, offset, length); this.value = StringCoding.decode(charset, bytes, offset, length); } public String(byte bytes[], String charsetName) throws UnsupportedEncodingException { this(bytes, 0, bytes.length, charsetName); } public String(byte bytes[], Charset charset) { this(bytes, 0, bytes.length, charset); } public String(byte bytes[], int offset, int length) { checkBounds(bytes, offset, length); this.value = StringCoding.decode(bytes, offset, length); } public String(byte bytes[]) { this(bytes, 0, bytes.length); } public String(StringBuffer buffer) { //为了保证StringBuffer的线程安全性语义 synchronized(buffer) { this.value = Arrays.copyOf(buffer.getValue(), buffer.length()); } } public String(StringBuilder builder) { this.value = Arrays.copyOf(builder.getValue(), builder.length()); } //返回String的长度 public int length() { return value.length; } //是否为空 public boolean isEmpty() { return value.length == 0; } //获取指定位置上的char public char charAt(int index) { if ((index < 0) || (index >= value.length)) { throw new StringIndexOutOfBoundsException(index); } return value[index]; } //返回指定位置的代码点 public int codePointAt(int index) { if ((index < 0) || (index >= value.length)) { throw new StringIndexOutOfBoundsException(index); } return Character.codePointAtImpl(value, index, value.length); } //返回指定位置之前的代码点 public int codePointBefore(int index) { int i = index - 1; if ((i < 0) || (i >= value.length)) { throw new StringIndexOutOfBoundsException(index); } return Character.codePointBeforeImpl(value, index, 0); } //返回指定范围的代码点点数 public int codePointCount(int beginIndex, int endIndex) { if (beginIndex < 0 || endIndex > value.length || beginIndex > endIndex) { throw new IndexOutOfBoundsException(); } return Character.codePointCountImpl(value, beginIndex, endIndex - beginIndex); } //返回从指定位置瞬移codePointOffset个代码点的索引 public int offsetByCodePoints(int index, int codePointOffset) { if (index < 0 || index > value.length) { throw new IndexOutOfBoundsException(); } return Character.offsetByCodePointsImpl(value, 0, value.length, index, codePointOffset); } //复制到指定字符数组 public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) { if (srcBegin < 0) { throw new StringIndexOutOfBoundsException(srcBegin); } if (srcEnd > value.length) { throw new StringIndexOutOfBoundsException(srcEnd); } if (srcBegin > srcEnd) { throw new StringIndexOutOfBoundsException(srcEnd - srcBegin); } System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin); } void getChars(char dst[], int dstBegin) { System.arraycopy(value, 0, dst, dstBegin, value.length); } //转成byte序列并封装到数组中 public byte[] getBytes(String charsetName) throws UnsupportedEncodingException { if (charsetName == null) throw new NullPointerException(); return StringCoding.encode(charsetName, value, 0, value.length); } //转成byte序列并封装到数组中 public byte[] getBytes(Charset charset) { if (charset == null) throw new NullPointerException(); return StringCoding.encode(charset, value, 0, value.length); } //使用默认字符集编码 public byte[] getBytes() { return StringCoding.encode(value, 0, value.length); } //判断元素是否相等 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; } //是否和sb相等 public boolean contentEquals(StringBuffer sb) { synchronized (sb) { return contentEquals((CharSequence) sb); } } //和传入的CharSequence比较 public boolean contentEquals(CharSequence cs) { if (value.length != cs.length()) return false; // Argument is a StringBuffer, StringBuilder if (cs instanceof AbstractStringBuilder) { char v1[] = value; char v2[] = ((AbstractStringBuilder) cs).getValue(); int i = 0; int n = value.length; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } // Argument is a String if (cs.equals(this)) return true; // Argument is a generic CharSequence char v1[] = value; int i = 0; int n = value.length; while (n-- != 0) { if (v1[i] != cs.charAt(i)) return false; i++; } return true; } //忽略大小写比较 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) { char ta[] = value; int to = toffset; char pa[] = other.value; int po = ooffset; // Note: toffset, ooffset, or len might be near -1>>>1. 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) { // If characters don't match but case may be ignored, // try converting both characters to uppercase. // If the results match, then the comparison scan should // continue. 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; } //比较 public int compareTo(String anotherString) { int len1 = value.length; int len2 = anotherString.value.length; //获取比较小的长度作为下界 int lim = Math.min(len1, len2); char v1[] = value; char v2[] = anotherString.value; int k = 0; while (k < lim) { char c1 = v1[k]; char c2 = v2[k]; if (c1 != c2) { return c1 - c2; } k++; } return len1 - len2; } //忽略大小写的比较 public int compareToIgnoreCase(String str) { return CASE_INSENSITIVE_ORDER.compare(this, str); } public int compare(String s1, String s2) { int n1 = s1.length(); int n2 = s2.length(); int min = Math.min(n1, n2); for (int i = 0; i < min; i++) { char c1 = s1.charAt(i); char c2 = s2.charAt(i); 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) { // No overflow because of numeric promotion return c1 - c2; } } } } return n1 - n2; } //测试两个字符串区域是否相等 public boolean regionMatches(int toffset, String other, int ooffset, int len) { char ta[] = value; int to = toffset; char pa[] = other.value; int po = ooffset; // Note: toffset, ooffset, or len might be near -1>>>1. if ((ooffset < 0) || (toffset < 0) || (toffset > (long)value.length - len) || (ooffset > (long)other.value.length - len)) { return false; } while (len-- > 0) { if (ta[to++] != pa[po++]) { return false; } } return true; } //是否以某个前缀开始 public boolean startsWith(String prefix) { return startsWith(prefix, 0); } //从指定位置是否已制定前缀开始 public boolean startsWith(String prefix, int toffset) { char ta[] = value; int to = toffset; char pa[] = prefix.value; int po = 0; int pc = prefix.value.length; // Note: toffset might be near -1>>>1. if ((toffset < 0) || (toffset > value.length - pc)) { return false; } while (--pc >= 0) { if (ta[to++] != pa[po++]) { return false; } } return true; } //是否是从指定的后缀结束 public boolean endsWith(String suffix) { return startsWith(suffix, value.length - suffix.value.length); } //返回指定的字符第一次出现的索引 public int indexOf(int ch) { return indexOf(ch, 0); } //从指定的索引开始搜索字符第一次出现的索引 public int indexOf(int ch, int fromIndex) { final int max = value.length; if (fromIndex < 0) { fromIndex = 0; } else if (fromIndex >= max) { return -1; } if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { final char[] value = this.value; for (int i = fromIndex; i < max; i++) { if (value[i] == ch) { return i; } } return -1; } else { return indexOfSupplementary(ch, fromIndex); } } //搜索字符最后一次出现的索引 public int lastIndexOf(int ch) { return lastIndexOf(ch, value.length - 1); } //从指定的字符位置反向搜索字符出现的位置 public int lastIndexOf(int ch, int fromIndex) { if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) { final char[] value = this.value; int i = Math.min(fromIndex, value.length - 1); for (; i >= 0; i--) { if (value[i] == ch) { return i; } } return -1; } else { return lastIndexOfSupplementary(ch, fromIndex); } } //搜索str第一次出现的位置 public int indexOf(String str) { return indexOf(str, 0); } //从fromIndex位置搜索str第一次出现的位置 public int indexOf(String str, int fromIndex) { return indexOf(value, 0, value.length, str.value, 0, str.value.length, fromIndex); } static int indexOf(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset, int targetCount, int fromIndex) { if (fromIndex >= sourceCount) { return (targetCount == 0 ? sourceCount : -1); } if (fromIndex < 0) { fromIndex = 0; } if (targetCount == 0) { return fromIndex; } char first = target[targetOffset]; //最大循环次数 int max = sourceOffset + (sourceCount - targetCount); for (int i = sourceOffset + fromIndex; i <= max; i++) { //找到第一个相等的位置 if (source[i] != first) { while (++i <= max && source[i] != first); } //找到了第一个 if (i <= max) { int j = i + 1; //计算最大循环到的角标 int end = j + targetCount - 1; for (int k = targetOffset + 1; j < end && source[j] == target[k]; j++, k++); //所有的都相等 if (j == end) { //找到的i-偏移量为最后的角标 return i - sourceOffset; } } } return -1; } //搜索字符串最后一次出现的索引 public int lastIndexOf(String str) { return lastIndexOf(str, value.length); } //从指定位置反向搜索字符串最后一次出现的位置 public int lastIndexOf(String str, int fromIndex) { return lastIndexOf(value, 0, value.length, str.value, 0, str.value.length, fromIndex); } static int lastIndexOf(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset, int targetCount, int fromIndex) { //最右边的位置 int rightIndex = sourceCount - targetCount; if (fromIndex < 0) { return -1; } if (fromIndex > rightIndex) { fromIndex = rightIndex; } //空字符串一定包含 if (targetCount == 0) { return fromIndex; } //找到target最后面的index int strLastIndex = targetOffset + targetCount - 1; //找到target的最后一位char char strLastChar = target[strLastIndex]; //能够循环到的最小的角标 int min = sourceOffset + targetCount - 1; //从哪里开始循环 int i = min + fromIndex; startSearchForLastChar: while (true) { //从后面开始找找到和最后面一位相等的char while (i >= min && source[i] != strLastChar) { i--; } //超界了 if (i < min) { return -1; } //source开始索引 int j = i - 1; //source最左边循环到的边界 int start = j - (targetCount - 1); int k = strLastIndex - 1; while (j > start) { if (source[j--] != target[k--]) { i--; continue startSearchForLastChar; } } return start - sourceOffset + 1; } } //返回从指定位置开始的新字符串 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); } //返回从开始位置到结束位置的CharSequence public CharSequence subSequence(int beginIndex, int endIndex) { return this.substring(beginIndex, endIndex); } //将指定字符串连接到此字符串的末尾 public String concat(String str) { int otherLen = str.length(); if (otherLen == 0) { return this; } int len = value.length; //复制到buf数组 char buf[] = Arrays.copyOf(value, len + otherLen); //将str复制到buf中 str.getChars(buf, len); return new String(buf, true); } //复制数组 void getChars(char dst[], int dstBegin) { System.arraycopy(value, 0, dst, dstBegin, value.length); } //用新值替换旧值 public String replace(char oldChar, char newChar) { if (oldChar != newChar) { int len = value.length; int i = -1; char[] val = value; /* avoid getfield opcode */ //找到oldChar的位置 while (++i < len) { if (val[i] == oldChar) { break; } } if (i < len) { char buf[] = new char[len]; //复制前半部分 for (int j = 0; j < i; j++) { buf[j] = val[j]; } //复制后半部分 while (i < len) { char c = val[i]; buf[i] = (c == oldChar) ? newChar : c; i++; } return new String(buf, true); } } return this; } //字符串是否匹配给定的正则表达式 public boolean matches(String regex) { return Pattern.matches(regex, this); } //是否包含某个字符串 public boolean contains(CharSequence s) { return indexOf(s.toString()) > -1; } //使用给定的正则表达式替换第一个字符串 public String replaceFirst(String regex, String replacement) { return Pattern.compile(regex).matcher(this).replaceFirst(replacement); } //使用给定的正则表达式替换所有字符串 public String replaceAll(String regex, String replacement) { return Pattern.compile(regex).matcher(this).replaceAll(replacement); } //使用指定的字符串替换 public String replace(CharSequence target, CharSequence replacement) { return Pattern.compile(target.toString(), Pattern.LITERAL).matcher( this).replaceAll(Matcher.quoteReplacement(replacement.toString())); } //使用给定的正则表达式拆分字符串 public String[] split(String regex) { return split(regex, 0); } //忽略空白 public String trim() { int len = value.length; int st = 0; char[] val = value; /* avoid getfield opcode */ //找到前面有空格的最大index while ((st < len) && (val[st] <= ' ')) { st++; } //找到后面有空格的最大index while ((st < len) && (val[len - 1] <= ' ')) { len--; } return ((st > 0) || (len < value.length)) ? substring(st, len) : this; } //复制为char数组 public char[] toCharArray() { // Cannot use Arrays.copyOf because of class initialization order issues char result[] = new char[value.length]; System.arraycopy(value, 0, result, 0, value.length); return result; } //使用指定的字符串格式化字符串 public static String format(String format, Object... args) { return new Formatter().format(format, args).toString(); } //返回Object的字符串表示形式 public static String valueOf(Object obj) { return (obj == null) ? "null" : obj.toString(); } public static String valueOf(char data[]) { return new String(data); } public static String valueOf(char data[], int offset, int count) { return new String(data, offset, count); } //复制数据返回一个String public static String copyValueOf(char data[], int offset, int count) { // All public String constructors now copy the data. return new String(data, offset, count); } public static String copyValueOf(char data[]) { return new String(data); } public static String valueOf(boolean b) { return b ? "true" : "false"; } public static String valueOf(char c) { char data[] = {c}; return new String(data, true); } public static String valueOf(int i) { return Integer.toString(i); } public static String valueOf(long l) { return Long.toString(l); } public static String valueOf(float f) { return Float.toString(f); } public static String valueOf(double d) { return Double.toString(d); } //返回字符串在常量池中的引用 public native String intern();