在Java中,字符串是对象,是描述字符的基本数据结构,也是程序设计中很重要的一类数据结构

Java专门为存储和处理字符串提供了两个类: String & StringBuffer

String类型对象的创建常见的有三种方法 :

1. 通过初始化 String str = "hellow";

2. 使用new关键字进行创建 String str = new String();

3. 通过类型转换来创建 String str = Double.toString(123.45);

String类常用方法的总结:

1.String求长度的方法 : public int length();

1 String s1 = Double.toString(1234.5678);
2 System.out.println("the length of s1 "+ s1 + " is :" +s1.length());                                                                  

 2.截取方法: public String substring(int begin); 返回从begin开始到最后的字符串

                   public String substring(int begin, int end);

1         String sub1 = s1.substring(5);
2         String sub2 = s1.substring(2, 7);
3         System.out.println(sub1);
4         System.out.println(sub2);

3.转字符串数组方法 : public String[] split(String regex);

1 /**
2 *常用的通过空格来分割字符串的方法
3 */                
4         String s2 = "my name is gap, i study in USTC!";
5         String snum[] = s2.split(" {1,}");
6         for(int i=0; i<snum.length; i++) {
7             System.out.println(snum[i]);
8         }

 

4.确定子字符串位置的方法:public int indexOf(String str);

                                    public int indexOf(String str, int fromIndex);         

1 int n1 = s2.indexOf("ga");
2 System.out.println(s2.indexOf('i'));            //输出为8即is中的i
3 System.out.println(s2.indexOf('i', 12));        //输出为16即,i中的i

 

 然后附上一道很有趣的面试题,同时也能够加深对java内存分配的理解:

 1 public class Test {
 2     public static void main(String[] args) {        
 3         //下列4行程序各创建了几个对象        
 4         String str1 = new String("hello");
 5         String str2 = "hello";
 6         
 7         String str3 = new String("hello");
 8         String str4 = "hello";
 9         
10         System.out.println(str1.equals(str3));
11         System.out.println(str1 == str2);
12         System.out.println(str1 == str3);
13         System.out.println(str2 == str3);
14         System.out.println(str2 == str4);
15     }
16 }

 

第4~8行语句在执行的时候分别创建了几个对象?10~14语句输出结果为什么?

第四行语句执行的时候会创建两个对象,第四条语句执行的顺序依次为 1.在栈上为str1分配空间 2.在String pool(String池)即内存data segment中创建对象“hello” 3.在堆中创建“hello”对象 4. 把引用赋给str

第五行语句执行的时候不会创建对象,因为首先会检查String池中是否有"hello"这个对象,有则str2直接指向String池中的“hello”;

第七行语句执行的时候会创建一个对象,即堆上创建"hello"对象; 

同理,第八行语句执行的时候也不会创建对象,值得注意的是由于String池中只有一个"hello"对象,因此str2与str4实际上指向同一块内存区域,因此str2 == str4 ;

运行结果如图所示:

                                               

 

总结一下,当JVM在运行用双引号引起来的一个字符串的代码时,即当Java虚拟机(JVM)遇到双引号操作符,它会先到String的对象池中去检查是否有一个字符串序列相同的对象,如果有,就取现成的对象;如果没有,则在对象池中创建,并且返回其引用。当然,如果有new关键字的话,除了上述步骤还会在堆中创建一个新的String对象。对象池的存在是为了避免频繁的创建和销毁对象而影响系统的性能。

看完String,再来看看StringBuffer,先看一段程序:

 1 public class TestStringBuffer {
 2     public static void main(String[] args) {
 3         String a = "a";
 4         String b = "b";
 5         String c = "c";
 6         String d = "d";
 7         String abcd = a + b + c + d;
 8     }
 9 
10 }

 

试想在以上的代码中,总共创建了几个对象?答案是 7 个。 首先对于变量a,b,c,d,它们都是通过双引号的形式创建的String对象。

而abcd变量则是通过4者通过+相连得到的,在相连的过程中,首先执行的是a+b操作,产生了ab字符串,然后加上c,产生了abc字符串,最后加上d得到abcd的String对象。

通过上例可以看出,通过String直接相加来拼接字符串的效率是极低,其中可能会产生大量冗余的字符串,例如ab,abc。

试想如果程序中有成千上万的字符串需要拼接,如果使用String的话此时JVM的负荷是很大的,会严重的影响到程序的性能。所以如果遇到大量字符串拼接操作的话,应该使用StringBuffer和StringBuilder类。

StringBuffer和StringBuilder类的功能和API类似,StringBuilder是线程安全的。

然后手贱把上面的程序改了下:

 1 public class TestStringBuffer {
 2     public static void main(String[] args) {
 3         String a = "a";
 4         String b = "b";
 5         String c = "c";
 6         String d = "d";
 7         String abcd = a + b + c + d;
 8         System.out.println(abcd == "abcd");
 9         
10         
11         String s1 = new String("a");
12         s1 = s1 + "b";
13         System.out.println(s1 == "ab");
14         
15         String s2 = "a" + "b";
16         System.out.println(s2 == "ab");
17     }
18 
19 }

 结果如图:

                                                          

然后上网查了下,也还没弄清楚其中的道理,先挖个坑,之后懂了再来把坑填上~~

 

posted on 2014-11-14 21:26  beyond_Acm  阅读(234)  评论(0编辑  收藏  举报