java.lang.string
String结构
这个类结构很简单。。
/** The value is used for character storage. */ private final char value[]; /** The offset is the first index of the storage that is used. */ private final int offset; /** The count is the number of characters in the String. */ private final int count; |
用了一个char数组来存储字符,然后offset是偏移(这个我还搞不懂有啥用),count是String的长度。
注意到String类是final的,不可以被继承,而且private final char value[];,只能赋值一次,赋值后就不能变了,只有从新生成一个String对象。
public String concat(String str)
public String concat(String str) { int otherLen = str.length(); if (otherLen == 0) { return this; } char buf[] = new char[count + otherLen]; getChars(0, count, buf, 0); str.getChars(0, otherLen, buf, count); return new String(0, count + otherLen, buf); } |
这段代码是连接两个String的,先拿个char数组当容器,从this和str分别取出char放入buf内,注意getChars方法的第四个参数,这个是说buf从count个开始拷贝。也就是说把两个string的char放在了一个char数组内,再返回一个新的String对象。(因为之前的String已经不可以改变)
public int indexOf(String str, int fromIndex)
public int indexOf(String str, int fromIndex) { return indexOf(value, offset, count, str.value, str.offset, str.count, fromIndex); } //source源字符,sourceOffset源偏移,sourceCount源长度 //target查找的字符 ... static int indexOf(char[] source, int sourceOffset, int sourceCount, char[] target, int targetOffset, int targetCount, int fromIndex) { //如果fromIndex比源字符还长(从0算起),并且查找的字符长度为0,那就返回源字符的长度,否则返回-1 if (fromIndex >= sourceCount) { return (targetCount == 0 ? sourceCount : -1); } if (fromIndex < 0) { fromIndex = 0; } //如果fromIndex比源字符短,查找的字符长度为0,直接返回fromIndex 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) { /* 如果j能到end,那就说明找到整个字符串啦,返回偏移 */ return i - sourceOffset; } } } return -1; } |
indexOf只要看它的查找方法,先找到第一个,然后再匹配剩下的。
public boolean equals(Object anObject)
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++]) return false; } return true; } } return false; } |
比较char~~
replace与replaceAll
public String replace(CharSequence target, CharSequence replacement) { return Pattern.compile(target.toString(), Pattern.LITERAL).matcher( this).replaceAll(Matcher.quoteReplacement(replacement.toString())); } public String replaceAll(String regex, String replacement) { return Pattern.compile(regex).matcher(this).replaceAll(replacement); } |
这两句真短啊。。用正则表达式来替换的。可以看出他们的区别。
replace只支持普通字符的替换哦,Pattern.LITERAL是指启用模式的字面值解析。Matcher.quoteReplacement(str)返回指定 String 的字面值替换 String。这个方法也就是替换\\为\\\\(四个反斜杠),$换为\\$。这样,它就不能用正则表达式了,但是看到依然是replaceAll,替换所有。
replaceAll很简单的一个正则表达式使用~~
要注意的是源字符串替换后内容并没有发生变化。