java string源码解析_java String部分源码解析

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

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

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拼接的效率较高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值