动手动脑4--有关字符串的一些东西
为何会出现这样的结果?
s0,s1,s2三个String类型的对象实际上指向的都是"Hello"这个常量,所以s0、s1、s2三者之间用==判断是否指向同一块内存肯定会返回布尔值true,这里的s0、s1、s2就很像C/C++里面的指针(Java官方说是没有指针的,其实Sun公司在写Java这门语言时干脆就把指针给封装成引用这种类型了,比较C++里面利用new字段开辟新空间的那句代码,和Java中利用new字段定义新对象的那句代码,其实是一样的,只不过那个*不用写了),而后面那两个是实实在在定义的两个新的不同的对象,尽管存的值相同,但是==对于两个对象而言比较的是他们指向的空间的地址,所以自然会返回布尔值false
这又有一个新的例子,和上面的区别就是为什么s1=="ab"会返回false,有人会问s1+="ab",s1="ab",那么两者指向不应该一样吗?
这个问题有点麻烦,主要就麻烦在s1+="b"这个操作不是在声明s1时完成的,要是和上面那个例子一样直接写String s1 = "a"+"b",那样还会是true。但是为什么分开写就不行呢,这跟String池有关。这个池维护所有不同的实例化后的字符串,比如,可能有a, ab, cde等等。当程序申请一个新的字符串的时候,如果这个字符串已经存在池中,那么这个字符串就会被返回,如果没有,就实例化一个新的,并且把它也放到池中。所以String s1 = "a"+"b",执行到这句时,会自动检查池中有没有"ab"这个串,如果有就将“ab”这个常量的地址交给s1,所以就解释了为什么上面那个例子是true。而这里这个由于分开了,是在s1+="b"这个过程中完成了s1 = new String("ab")这么个隐藏的过程,所以这里是false。至于equals那个方法,这里不讲,下面的例子会重点提到。
接下来就说说String类中一个重要的方法——equals,用来比较两个字符串的内容是否一样。
方法的源码:
1 public boolean equals(Object anObject) { 2 if (this == anObject) { 3 return true; 4 } 5 if (anObject instanceof String) { 6 String anotherString = (String) anObject; 7 int n = value.length; 8 if (n == anotherString.value.length) { 9 char v1[] = value; 10 char v2[] = anotherString.value; 11 int i = 0; 12 while (n-- != 0) { 13 if (v1[i] != v2[i]) 14 return false; 15 i++; 16 } 17 return true; 18 } 19 } 20 return false; 21 }
从上面的代码中可以看到,
(1)String类中的equals首先比较地址,如果是同一个对象的引用,可知对象相等,返回true。
(2)若果不是同一个对象,equals方法挨个比较两个字符串对象内的字符,只有完全相等才返回true,否则返回false。
参考一段代码:
String str = "abc";
String str1 = str.trim().toUpperCase().concat("defg");
输出str1,会显示"ABCdefg",trim()的作用是去掉字符串首位的空格,toUpperCase()的作用是将小写字符大写化,而concat(String s)的作用是将参数s加在字符串的后面,由此可以写一个MyCounter类,添加两个方法increase()和decrease(),返回值都是int型(或者利用重载计算多种类型),代码如下:
1 public class MyCounter{ 2 private int value; 3 public MyCounter(int value){ 4 this.value =value; 5 } 6 public int increase(int val){ 7 value+=val; 8 return value; 9 } 10 public int decrease(int val){ 11 value-=val; 12 return value; 13 } 14 public String toString(){ 15 return String.valueOf(value); 16 } 17 }
MyCounter counter1=new MyCounter(1);
MyCounter counter2=counter1.increase(100).decrease(2).increase(3);
System.out.print(counter1); 在主函数中写入这些代码,会输出102
最后再来说说几个常用的String类中的常用方法:
public int length():返回值类型为int型,返回当前字符串的有效长度
public void charAt(int num):num为索引值,返回字符串中下标为num的字符,如果越界会抛出异常
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin):截取字符数组,要复制的第一个字符在索引srcBegin处,被复制的最后一个字符是在的索引srcEnd1即要复制的字符总数是srcEnd srcBegin处。字符被复制到子数组的夏令时开始在指数dstBegin和结束于索引:dstbegin + (srcEnd-srcBegin) - 1
public String replace(char oldChar,char newChar):替换字符,利用newchar替换oldchar,然后返回新的字符串
UpperCase()和toLoserCase()一个转成大写,一个转成小写
trim():去掉字符串首尾两端所有的空格
至于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;
}
将一个字符串转换成一个Char型的字符数组,并且这里面的字符是原封不动的拿进去的,意思就是说,包含一切字符均转换成相应的字符数组。
==========================================================================================================================================================================
End