动手动脑1:
请运行以下示例代码StringPool.java,查看其输出结果。如何解释这样的输出结果?从中你能总结出什么?
在Java中,内容相同的字串常量(“Hello”)只保存一份以节约内存,所以s0,s1,s2实际上引用的是同一个对象。编译器在编译s2一句时,会去掉“+”号,直接把两个字串连接起来得一个字串(“Hello”)。这种优化工作由Java编译器自动完成。当直接使用new关键字创建字符串对象时,虽然值一致(都是“Hello”),但仍然是两个独立的对象。==在此比较是它们的地址,因为开辟空间,初始化的不同,所以地址不同,所以结果是False;
从上述代码中可得到:
给字串变量赋值意味着:两个变量(s1,s2)现在引用同一个字符串对象“a”!
String对象的内容是只读的,使用“+”修改s1变量的值,实际上是得到了一个新的字符串对象,其内容为“ab”,它与原先s1所引用的对象”a”无关,所以,s1==s2返回false;
代码中的“ab”字符串是一个常量,它所引用的字符串与s1所引用的“ab”对象无关。
String.equals()方法可以比较两个字符串的内容。
动手动脑 2::
String.equal() jdk源代码的源代码如下:
使用说明:
用于判断两个字符串的值是否相等
阅读笔记:
方法体实质上是先比较两个字符串的长度是否相等,然后,在将字符串转化为字符数组,通过比较对应位置的字符是否相同,进而来判断两个字符串值是否相同。
该方法首先判断this == anObject ?,也就是说判断要比较的对象和当前对象是不是同一个对象,如果是直接返回 true,如不是再继续比较,然后在判断
anObject 是不是 String类型的,如果不是,直接返回 false,如果是他还是先比较了两个数组的长度,不一样直接返回 false,一样再逐一比较字符数组的值。
动手动脑 3:
每当一个对象创建后,Java虚拟机会给这个对象分配一个引用自身的指针,这个指针的名字就是 this。因此,this只能在类中的非静态方法中使用,静态方法和静态的代码块中绝对不能出现this的用法。因为这里需要实现级联调用特性,所以将方法返回值设为对象类型(以该类作类型),即方法本身可再调用方法。
String.concat()函数
将字符串与字符串连接起来。创建新的字符数组,新的length=两字符串长度之和,将长度,首元赋给字符数组
String.trim()函数
去掉字符串首尾的空格,为防止不必要的空格产生的错误,该方法返回字符串对象的一个副本。
String.toUpperCase()函数
string.toUpperCase()为将字符串string中字符变为大写。
所以实现级调的实例如下:
package String;
public class MyCounter {
int num;
public MyCounter increase(int j)//public是对别的类公开,该方法需要返回MyCounter对象,所以应用this指针,下面同理
{
num+=j;
return this; }
public MyCounter decrease(int n)
{
num-=n;
return this;
}
MyCounter(int k)
{
num=k;
}
public static void main(String[] args) {
MyCounter counter1=new MyCounter(1);
MyCounter counter2=counter1.increase(100).decrease(2).increase(3);
System.out.println("The result is:"+counter2.num);
}
}
执行结果:
Java中String类的length()、charAt()、getChars()、replace()、toUpperCase()、toLowerCase()、trim()、toCharArray()使用说明
在Java语言中String类有很多以处理函数,例如length()、charAt()、getChars()、replace()、toUpperCase()、toLowerCase()、trim()、toCharArray()等,用法如下:
1 string.length()是用来求字符串的长度,返回值为字符串的长度。
2 string.charAt()为取该字符串某个位置的字符,从0开始,例如string.charAt(0)就会返回该字符串的第一个字符。
3 string.getChars()为将这个字符串中的字符复制到目标字符数组。
4 string.replace()为将原string 中的元素或子串替换。返回替换后的string。
5 string.toUpperCase()为将字符串string中字符变为大写。
6 string.toLowerCase()为将字符串string中字符变为小写。
7 string.trim()为去除字符串的头为空格。
8 string.toCharArray()为将字符串转换为字符数组。
举个例子:
public class Example {
public static void main(String args[])
{
String s1=new String("you are a student");
String s2=new String("HOW ARE YOU");
String s3=new String(" Hello "); //string.length()求长度
System.out.println("length of string is:"+s1.length()); //string.charAt()取指定位置字符
System.out.println("the first char of string::"+s1.charAt(0)); //string.getChars()为将这个字符串中的字符复制到目标字符数组。
char[] c = new char[s1.length()];
s1.getChars(0, s1.length(), c, 0);
System.out.print("输出数组:");
for(int i=0;i<s1.length()-1; i++)
{
System.out.print(" "+c[i]);
} //string.replace()为将原string 中的元素或子串替换。返回替换后的string。
System.out.println("\ns1替换为s2后是:"+s1.replace(s1, s2)); //string.toUpperCase()为将字符串string中字符变为大写。
System.out.println("s1变为大写后为:"+s1.toUpperCase()); //string.toLowerCase()为将字符串string中字符变为小写。
System.out.println("s2变为小写后为:"+s2.toLowerCase()); //string.trim()为去除字符串的头为空格。
System.out.println("s1变为大写后为:"+s3.trim()); //string.toCharArray()为将字符串转换为字符数组
char a[]=s1.toCharArray();
System.out.println("转换为数组a后a[1]= "+a[1]); }
}
结果截图:
各方法的源码如下:
1.String.length()
public int length() {
return value.length;
}
2.String.charAt()
public char charAt(int index) {
if ((index < 0) || (index >= value.length)) {
throw new StringIndexOutOfBoundsException(index);
}
return value[index];
}
3.String.getChars()
void getChars(char dst[], int dstBegin) {
System.arraycopy(value, 0, dst, dstBegin, value.length);
}
1.//将value从srcBegin到srcEnd的字符串复制到dst的dstBegin处
2.public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
3.{
4. if (srcBegin < 0)
5. throw new StringIndexOutOfBoundsException(srcBegin);
6. if ((srcEnd < 0) || (srcEnd > count))
7. throw new StringIndexOutOfBoundsException(srcEnd);
8. if (srcBegin > srcEnd)
9. throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
10. //将value从srcBegin起的(srcEnd-srcBegin)个字符复制到dst的dstBegin位置处
11. System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}
4.String.replace()方法
- replace 的参数是 char 和 CharSequence,即可以支持字符的替换, 也支持字符串的替换, 把源字符串中的某一字符或字符串全部换成指定的字符或字符串
1.public AbstractStringBuilder replace(int start, int end, String str) {
2. if (start < 0)
3. throw new StringIndexOutOfBoundsException(start);
4. if (start > count)
5. throw new StringIndexOutOfBoundsException("start > length()");
6. if (start > end)
7. throw new StringIndexOutOfBoundsException("start > end");
8. if (end > count)
9. end = count;
10. int len = str.length();
11. //计算新长度
12. int newCount = count + len - (end - start);
13. //扩容
14. ensureCapacityInternal(newCount);
15. //复制,实际上是删除start到end间的字符串
16. System.arraycopy(value, end, value, start + len, count - end);
17. //复制
18. str.getChars(value, start);
19. //更新长度
20. count = newCount;
21. return this;
22.}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;
} - 5. String.toUpperCase()
public String toUpperCase() {
return toUpperCase(Locale.getDefault());
}
public String toUpperCase(Locale locale) {
if (locale == null) {
throw new NullPointerException();
} int firstLower;
final int len = value.length; /* Now check if there are any characters that need to be changed. */
scan: {
for (firstLower = 0 ; firstLower < len; ) {
int c = (int)value[firstLower];
int srcCount;
if ((c >= Character.MIN_HIGH_SURROGATE)
&& (c <= Character.MAX_HIGH_SURROGATE)) {
c = codePointAt(firstLower);
srcCount = Character.charCount(c);
} else {
srcCount = 1;
}
int upperCaseChar = Character.toUpperCaseEx(c);
if ((upperCaseChar == Character.ERROR)
|| (c != upperCaseChar)) {
break scan;
}
firstLower += srcCount;
}
return this;
} /* result may grow, so i+resultOffset is the write location in result */
int resultOffset = 0;
char[] result = new char[len]; /* may grow */ /* Just copy the first few upperCase characters. */
System.arraycopy(value, 0, result, 0, firstLower); String lang = locale.getLanguage();
boolean localeDependent =
(lang == "tr" || lang == "az" || lang == "lt");
char[] upperCharArray;
int upperChar;
int srcChar;
int srcCount;
for (int i = firstLower; 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) {
upperChar = ConditionalSpecialCasing.toUpperCaseEx(this, i, locale);
} else {
upperChar = Character.toUpperCaseEx(srcChar);
}
if ((upperChar == Character.ERROR)
|| (upperChar >= Character.MIN_SUPPLEMENTARY_CODE_POINT)) {
if (upperChar == Character.ERROR) {
if (localeDependent) {
upperCharArray =
ConditionalSpecialCasing.toUpperCaseCharArray(this, i, locale);
} else {
upperCharArray = Character.toUpperCaseCharArray(srcChar);
}
} else if (srcCount == 2) {
resultOffset += Character.toChars(upperChar, result, i + resultOffset) - srcCount;
continue;
} else {
upperCharArray = Character.toChars(upperChar);
} /* Grow result if needed */
int mapLen = upperCharArray.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] = upperCharArray[x];
}
resultOffset += (mapLen - srcCount);
} else {
result[i + resultOffset] = (char)upperChar;
}
}
return new String(result, 0, len + resultOffset);
}
6.String.toLowerCase()
public String toLowerCase() {
return toLowerCase(Locale.getDefault());
} 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);
}
7.String.trim()
public String trim() {
int len = value.length;
int st = 0;
char[] val = value; /* avoid getfield opcode */ while ((st < len) && (val[st] <= ' ')) {
st++;
}
while ((st < len) && (val[len - 1] <= ' ')) {
len--;
}
return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}
8.String.toCharArray()
public char[] toCharArray() {
// Cannot use Arrays.copyOf because of class initialization order issues
char result[] = new char[value.length];
System.arraycopy(value, 0, result, 0, value.length);
return result;
}
9.String.concat()函数
创建新的字符数组,新的length=两字符串长度之和,将长度,首元赋给字符数组
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);
}