动手动脑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

posted @ 2017-10-25 18:09  messi2017  阅读(173)  评论(0编辑  收藏  举报