记录下阅读源码过程中遇到的有用的知识
1.String位final类,不可继承,其声明为
public final class String
private char value[]`存储.
implements java.io.Serializable, Comparable<String>, CharSequence,String的内容由
2.方法public int codePointAt(int index)
直接返回索引下的char元素的Unicode code point,如
String Str = "012345Str";
//直接返回索引下的char元素的Unicode code point
System.out.println(Str.codePointAt(0));
可以得到0的Unicode code point为48,这样获得字母数字和特殊符号的ASCII码很方便。
源码实现为:
public int codePointAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return Character.codePointAtImpl(value, index, value.length);
}
3.函数public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)可以将String截取某部分放到char []中,函数的实现方法为
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);
}
还不如先使用substring()截取某一段,再使用toCharArray()转换成char[]更加方便。
4.重写equals方法
public boolean equals(Object anObject) {
if (this == anObject) {//当前要比较对象为同一对象,返回true,满足自反性
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;
}
5.String类对compareTo方法的实现方法
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);//以最小长度的string为基准
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;//返回值为第一个不等char元素的差值
}
k++;
}
return len1 - len2;//返回值为两个String的长度差
}
当然,这种版本的compareTo方法不会令所有人满意,比如我就不太满意,哈哈。
6.startsWith(String prefix,int rooffset)方法.该方法用于判断String是否以prefix为前缀,这个方法实现起来比较简单。
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) 判断String是否以suffix为后缀,直接调用startsWith就可以了。
public boolean endsWith(String suffix) {
return startsWith(suffix, value.length - suffix.value.length);
}
7.重写hashCode()方法.
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
使用了一个简单的多项式散列函数算出了hash值,简单的hash函数可以降低计算开销,加快程序速度(在满足hash要求的前提下),由 h = 31 * h + val[i]可以看出,不同的String完全有可能具有相同的hashCode,所以只根据hashCode值相同不能说明两个String相等,需要通过equals()方法才能准确地判断。
8.字符串连接函数contact()
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}
做字符串连接时比较方便
String Str = "012345Str";
System.out.println(Str.concat(" I love Java"));
9.字符替换函数repalce(char oldChar,char newChar),用于将String中所有的oldChar替换为newChar.
public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
int len = value.length;
int i = -1;
char[] val = value; /* avoid getfield opcode */
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;
}
10.正则表达式匹配函数public boolean matches(String regex).
public boolean matches(String regex) {
return Pattern.matches(regex, this);
}
如:
String str = "xxx@mail2.sysu.edu.cn";
// 邮箱验证规则
String regEx = "[a-zA-Z_]{1,}[0-9]{0,}@(([a-zA-z0-9]-*){1,}\\.){1,3}[a-zA-z\\-]{1,}";
// 编译正则表达式
System.out.println(str.matches(regEx));
打印结果为true.
11.正则表达式替换函数replaceAll(String regex, String replacement)
public String replaceAll(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}
12.String的最后一个方法就是public native String intern();方法了,方法的作用javadoc里说得很清楚:
/**
* Returns a canonical representation for the string object.
* <p>
* A pool of strings, initially empty, is maintained privately by the
* class {@code String}.
* <p>
* When the intern method is invoked, if the pool already contains a
* string equal to this {@code String} object as determined by
* the {@link #equals(Object)} method, then the string from the pool is
* returned. Otherwise, this {@code String} object is added to the
* pool and a reference to this {@code String} object is returned.
* <p>
* It follows that for any two strings {@code s} and {@code t},
* {@code s.intern() == t.intern()} is {@code true}
* if and only if {@code s.equals(t)} is {@code true}.
* <p>
* All literal strings and string-valued constant expressions are
* interned. String literals are defined in section 3.10.5 of the
* <cite>The Java™ Language Specification</cite>.
*
* @return a string that has the same contents as this string, but is
* guaranteed to be from a pool of unique strings.
*/
还没找到intern()的源码,哈哈