代码改变世界

java string

2012-01-06 16:44  Rainbow  阅读(777)  评论(0编辑  收藏  举报

在任何编程语言 String类多是被使用最频繁的数据类型。java也是一样

String对象的初始化

1.String str=”this is a string”;

2.String str2=new String(“this is another string”);

通常情况我们会使用第一种定义方式,String在java的地位是很高的待遇,对他做了特别优化,被称为“非可变类型”。言下之意就是当它完成初始化以后就不能有任何变化了,好比对它做增加,删除等操作,多会有复制现象出现。

第二种方式是按照面向对象的标准语法,在内存使用上存在比较大的浪费。例如String str2=new String(“this is another string”);实际上创建了两个String对象,一个是”abc”对象,存储在常量空间中,一个是使用new关键字为对象str2申请的空间。

通过以上的说明,我们就有一个比较有趣的现象,而且是面试当中出现非常高的问题。就是比较两个字符串是否相等。


猜猜会出现什么结果。

s1==s2
s1.equals(s2)
s1.equals(s3)

下面我们来说一下为啥会有这样的结果。首先我们需要了解的是在java中 == 和equals的区别,同样是判断相等条件的。equals的作用是判断两个变量的值是否相等。== 当左右值为基本类型时判断值是否相等,当为引用类型时,判断两个引用变量是否指向同一个地址。

  1. s1==s2 这个有比较难解释了。明明是两个不同的变量,怎么可能引用的地址会是一样的呢。这里就到了我上面提到了为啥说java对String类型做了优化了。

String s1="Hello Rainbow";
String s2="Hello Rainbow";
String s3=new String("Hello Rainbow");

表面上看这三句回实例化3个String对象,实际上是两个。在java中有一个叫“字符数据池”的内存管理机制,在对s2赋值之前,会检查池中有没有相同的数据,如果有,则直接引用;若没有,系统会实例化这个String的对象;而执行到String s3=new String("Hello Rainbow");系统会直接实例化该对象,而不会在池中查找。也不会将这个对象放在池中。
你可能会问,如果改动str1或str2时会不会改动另外一个引用的值。答案是不会。系统会首先在池中查找有没有相同的对象,如果没有,会实例化这个对象。
这样 s1==s2 就解释的过去了。原来是”字符数据池“作怪啊。
 
s1.equals(s2) 这样比较好解释了。他们两个的内容是完全一样的。所以肯定会打印出 s1.equals(s2)的。
  1. s1==s3 这个肯定就不会相等了。因为s3 上存放着 new String("Hello Rainbow"); 对象的地址呢(这是个形象的比喻)。那这个地址值肯定不会是s1 的地址。
  2. s1.equals(s3) 这个其实还是”字符数据池“在作怪。因为new 这个操作还事先去池里面找是否有这样的内容存在,如果存在就直接把地址给s3就行了。这样s1,s2 其实多是指向同一地址的。那如果将其中一个的内容改了会不会影响其他的两个呢。答案是 不会的。其记住String 类型的创建原则,先去池里面找是否有这样的内容 如果有就不创建了,直接用。
            s2="xxx";
            System.out.println(s1);
            System.out.println(s2);
            System.out.println(s3); 

            输出结果是:

    Hello Rainbow
    xxx
    Hello Rainbow

    String类常用方法

    concat方法

    该方法的作用是进行字符串的连接,将两个字符串连接以后形成一个新的字符串。其实在实际使用时,语法上提供了一种更简单的形式,就是使用“+”进行字符串的连接。

    equals方法

    该方法的作用是判断两个字符串对象的内容是否相同。如果相同则返回true,否则返回false。

    而使用“==”比较的是两个对象在内存中存储的地址是否一样

    getBytes方法

    该方法的作用是将字符串转换为对应的byte数组,从而便于数据的存储和传输。

    length方法

    该方法的作用是返回字符串的长度,也就是返回字符串中字符的个数。中文字符也是一个字符。

    split方法

    该方法的作用是以特定的字符串作为间隔,拆分当前字符串的内容,一般拆分以后会获得一个字符串数组。

    substring方法

    该方法的作用是取字符串中的“子串”,所谓“子串”即字符串中的一部分。

    valueOf方法

    该方法的作用是将其它类型的数据转换为字符串类型。需要注意的是,基本数据和字符串对象之间不能使用以前的强制类型转换的语法进行转换。

    另外,由于该方法是static方法,所以不用创建String类型的对象即可。例如:

             int n = 10;

             String s = String.valueOf(n);

    则字符串s的值是”10”。虽然对于程序员来说,没有发生什么变化,但是对于程序来说,数据的类型却发生了变化。

    介绍一个简单的应用,判断一个自然数是几位数字的逻辑代码如下:

             int n = 12345;

             String s = String.valueOf(n);

             int len = s.length();

    则这里字符串的长度len,就代表该自然数的位数。这种判断比数学判断方法在逻辑上要简单一些。

     

    关于String类的使用就介绍这么多,其它的方法以及这里到的方法的详细声明可以参看对应的API文档。