【JDK1.8源码阅读】String.class

常量

  1. String底层是使用字符数组存储的
  2. 所有String字符串被创建后就不可改变,因此创建后的字符串底层是共享的。
  3. String类里面的value包括一个hash(int)private final char value[],广义上只要两者任一值不同,既是不同。

public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
	private final char value[];
	private int hash;
	private static final long serialVersionUID = -6849794470754667710L;
	private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0];
	public String() {
		this.value = "".value;//this.value = "".value,意思指长度为零的空字符串
	}
	public String(String original) {
		this.value = original.value;
		this.hash = original.hash;
	}
	public String(char value[]) {
		this.value = Arrays.copyOf(value, value.length);
	}

方法

compareTo

compareTo和compareToIgnoreCase两个方法,由源码可看出:

  1. 首先取出两个字符串的长度,比较较小的长度内,两者是否相等。
  2. 若不相等,则直接返回该位置字符的ASCII码相减后的值。
  3. 若各位置都相等,则将两个字符串长度的差值返回。
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;
//不如直接returnlen1-len2,这一段何用
		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);
	}

regionMatches

regionMatches() 方法用于检测两个字符串在一个区域内是否相等。

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 regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) {
		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;
	}

startsWith

startsWith() 方法用于检测字符串是否以指定的前缀开始

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 startsWith(String prefix) {
		return startsWith(prefix, 0);
	}

	public boolean endsWith(String suffix) {
		return startsWith(suffix, value.length - suffix.value.length);
	}
public class Test {
public static void main(String args[]) {
    String Str = new String("www.runoob.com");
    System.out.print("返回值 :" );
    System.out.println(Str.startsWith("www") );//true
    System.out.print("返回值 :" );
    System.out.println(Str.startsWith("runoob") );//false
    System.out.print("返回值 :" );
    System.out.println(Str.startsWith("runoob", 4) );//true
}
}

indexOf

字符串的IndexOf()方法搜索在该字符串上是否出现了作为参数传递的字符串,如果找到字符串,则返回字符的起始位置

public int indexOf(String str) {
		return indexOf(str, 0);
	}

	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, String target, int fromIndex) {
		return indexOf(source, sourceOffset, sourceCount, target.value, 0, target.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++) {
			/* Look for first character. */
			if (source[i] != first) {
				while (++i <= max && source[i] != first)
					;
			}
			/* Found first character, now look at the rest of v2 */
			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) {
					/* Found whole string. */
					return i - sourceOffset;
				}
			}
		}
		return -1;
	}

substring

返回一个新字符串,它是此字符串的一个子字符串。该子字符串始于指定索引处的字符,一直到此字符串末尾。

异常:如果 beginIndex 为负或大于此 String 对象的长度,则抛出IndexOutOfBoundsException 
例  :  "unhappy".substring(2)   returns"happy"
   	"mybaby".substring(3)   returns"aby"
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);
	}

	public CharSequence subSequence(int beginIndex, int endIndex) {
		return this.substring(beginIndex, endIndex);
	}

replace

replace() 方法通过用 newChar 字符替换字符串中出现的所有 oldChar 字符,并返回替换后的新字符串。

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()));
	}

toLowerCase

public String toLowerCase(Locale locale) {
		if (locale == null) {
			throw new NullPointerException();
		}

		int firstUpper;
		final int len = value.length;

		/* Now check if there are any characters that need to be changed. */
		scan: {
			for (firstUpper = 0; firstUpper < len;) {
				char c = value[firstUpper];
				if ((c >= Character.MIN_HIGH_SURROGATE) && (c <= Character.MAX_HIGH_SURROGATE)) {
					int supplChar = codePointAt(firstUpper);
					if (supplChar != Character.toLowerCase(supplChar)) {
						break scan;
					}
					firstUpper += Character.charCount(supplChar);
				} else {
					if (c != Character.toLowerCase(c)) {
						break scan;
					}
					firstUpper++;
				}
			}
			return this;
		}

		char[] result = new char[len];
		int resultOffset = 0; /* result may grow, so i+resultOffset
								 * is the write location in result */

		/* Just copy the first few lowerCase characters. */
		System.arraycopy(value, 0, result, 0, firstUpper);

		String lang = locale.getLanguage();
		boolean localeDependent = (lang == "tr" || lang == "az" || lang == "lt");
		char[] lowerCharArray;
		int lowerChar;
		int srcChar;
		int srcCount;
		for (int i = firstUpper; i < len; i += srcCount) {
			srcChar = (int) value[i];
			if ((char) srcChar >= Character.MIN_HIGH_SURROGATE && (char) srcChar <= Character.MAX_HIGH_SURROGATE) {
				srcChar = codePointAt(i);
				srcCount = Character.charCount(srcChar);
			} else {
				srcCount = 1;
			}
			if (localeDependent || srcChar == '\u03A3' || // GREEK CAPITAL LETTER SIGMA
					srcChar == '\u0130') { // LATIN CAPITAL LETTER I WITH DOT ABOVE
				lowerChar = ConditionalSpecialCasing.toLowerCaseEx(this, i, locale);
			} else {
				lowerChar = Character.toLowerCase(srcChar);
			}
			if ((lowerChar == Character.ERROR) || (lowerChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
				if (lowerChar == Character.ERROR) {
					lowerCharArray = ConditionalSpecialCasing.toLowerCaseCharArray(this, i, locale);
				} else if (srcCount == 2) {
					resultOffset += Character.toChars(lowerChar, result, i + resultOffset) - srcCount;
					continue;
				} else {
					lowerCharArray = Character.toChars(lowerChar);
				}

				/* Grow result if needed */
				int mapLen = lowerCharArray.length;
				if (mapLen > srcCount) {
					char[] result2 = new char[result.length + mapLen - srcCount];
					System.arraycopy(result, 0, result2, 0, i + resultOffset);
					result = result2;
				}
				for (int x = 0; x < mapLen; ++x) {
					result[i + resultOffset + x] = lowerCharArray[x];
				}
				resultOffset += (mapLen - srcCount);
			} else {
				result[i + resultOffset] = (char) lowerChar;
			}
		}
		return new String(result, 0, len + resultOffset);
	}

	public String toLowerCase() {
		return toLowerCase(Locale.getDefault());
	}

valueOf

valueOf将传入的变量转成String

	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);
	}
	public static String copyValueOf(char data[], int offset, int count) {
		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);
	}
valueOf与copyValueOf区别

看以下代码可知,两者完全没有区别的。面试官要是用这个问题秀优越感,直接PASS掉这家公司就好。

摘:String的底层是由char[]实现的:通过一个char[]类型的value属性!早期的String构造器的实现呢,不会拷贝数组的,直接将参数的char[]数组作为String的value属性。然后test[0] = ‘A’;
将导致字符串的变化。为了避免这个问题,提供了copyValueOf方法,每次都拷贝成新的字符数组来构造新的String对象。但是现在的String对象,在构造器中就通过拷贝新数组实现了,所以这两个方面在本质上已经没区别了。https://zhidao.baidu.com/question/195140952.html

public static String valueOf(char data[]) {
		return new String(data);
	}
public static String copyValueOf(char data[]) {
		return new String(data);
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值