String类型的成员变量
/**String的属性值*/
private final charvalue[];/**The offset is the first index of the storage that is used.*/
/**数组被使用的开始位置**/
private final intoffset;/**The count is the number of characters in the String.*/
/**String中元素的个数**/
private final intcount;/**Cache the hash code for the string*/
/**String类型的hash值**/
private int hash; //Default to 0
/**use serialVersionUID from JDK 1.0.2 for interoperability*/
private static final long serialVersionUID = -6849794470754667710L;
有上面的成员变量可以知道String类的值是final类型的,不能被改变的,所以只要一个值改变就会生成一个新的String类型对象,存储String数据也不一定从数组的第0个元素开始的,而是从offset所指的元素开始。
如下面的代码是生成了一个新的对象,最后的到的是一个新的值为“bbaa”的新的String的值。
String a = new String("bb");
String b= new String("aa");
String c= a + b;
也可以说String类型的对象是长度不可变的,String拼接字符串每次都要生成一个新的对象,所以拼接字符串的效率肯定没有可变长度的StringBuffer和StringBuilder快。
然而下面这种情况却是很快的拼接两个字符串的:
String a = "aa" + "bb";
原因是:java对它字符串拼接进行了小小的优化,他是直接把“aa”和“bb”直接拼接成了“aabb”,然后把值赋给了a,只需生成一次String对象,比上面那种方式减少了2次生成String,效率明显要高很多。
下面我们来看看String的几个常见的构造方法吧
1、无参数的构造方法:
publicString() {this.offset = 0;this.count = 0;this.value = new char[0];
}
2、传入一个Sring类型对象的构造方法
publicString(String original) {int size =original.count;char[] originalValue =original.value;char[] v;if (originalValue.length >size) {//The array representing the String is bigger than the new//String itself. Perhaps this constructor is being called//in order to trim the baggage, so make a copy of the array.
int off =original.offset;
v= Arrays.copyOfRange(originalValue, off, off+size);
}else{//The array representing the String is the same//size as the String, so no point in making a copy.
v =originalValue;
}this.offset = 0;this.count =size;this.value =v;
}
3、传入一个字符数组的构造函数
public String(charvalue[]) {int size =value.length;this.offset = 0;this.count =size;this.value =Arrays.copyOf(value, size);
}
4、传入一个字符串数字,和开始元素,元素个数的构造函数
public String(char value[], int offset, intcount) {if (offset < 0) {throw newStringIndexOutOfBoundsException(offset);
}if (count < 0) {throw newStringIndexOutOfBoundsException(count);
}//Note: offset or count might be near -1>>>1.
if (offset > value.length -count) {throw new StringIndexOutOfBoundsException(offset +count);
}this.offset = 0;this.count =count;this.value = Arrays.copyOfRange(value, offset, offset+count);
}
由上面的几个常见的构造函数可以看出,我们在生成一个String对象的时候必须对该对象的offset、count、value三个属性进行赋值,这样我们才能获得一个完成的String类型。
常见函数:
1、判断两个字符串是否相等的函数(Equal):其实就是首先判断比较的实例是否是String类型数据,不是则返回False,是则比较他们每一个字符元素是否相同,如果都相同则返回True,否则返回False
public booleanequals(Object anObject) {if (this ==anObject) {return true;
}if (anObject instanceofString) {
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;
}
2、比较两个字符串大小的函数(compareTo):输入是两个字符串,返回的0代表两个字符串值相同,返回小于0则是第一个字符串的值小于第二个字符串的值,大于0则表示第一个字符串的值大于第二个字符串的值。
比较的过程主要如下:从两个字符串的第一个元素开始比较,实际比较的是两个char的ACII码,加入有不同的值,就返回第一个不同值的差值,否则返回0
public intcompareTo(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
}
k++;
}
}else{while (n-- != 0) {char c1 = v1[i++];char c2 = v2[j++];if (c1 !=c2) {return c1 -c2;
}
}
}return len1 -len2;
}
View Code
3、判断一个字符串是否以prefix字符串开头,toffset是相同的长度
public boolean startsWith(String prefix, inttoffset) {char ta[] =value;int to = offset +toffset;char pa[] =prefix.value;int po =prefix.offset;int pc =prefix.count;//Note: toffset might be near -1>>>1.
if ((toffset < 0) || (toffset > count -pc)) {return false;
}while (--pc >= 0) {if (ta[to++] != pa[po++]) {return false;
}
}return true;
}public inthashCode() {int h =hash;if (h == 0) {int off =offset;char val[] =value;int len =count;for (int i = 0; i < len; i++) {
h= 31*h + val[off++];
}
hash=h;
}returnh;
}
4、连接两个字符串(concat)
publicString 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);
}
连接字符串的几种方式
1、最直接,直接用+连接
String a = new String("bb");
String b= new String("aa");
String c= a + b;
2、使用concat(String)方法
String a = new String("bb");
String b= new String("aa");
String d= a.concat(b);
3、使用StringBuilder
String a = new String("bb");
String b= new String("aa");
StringBuffer buffer= new StringBuffer().append(a).append(b);
第一二中用得比较多,但效率比较差,使用StringBuilder拼接的效率较高。