现在的位置: 首页 > 综合 > 正文

String类使用内存解析及效率问题

2013年08月17日 ⁄ 综合 ⁄ 共 2196字 ⁄ 字号 评论关闭

参考原文:http://blog.csdn.net/xiazdong/article/details/6723101#

一、两种实例化方式:

String str = “abc”;

String str = new String("abc");

一个字符串就是String的匿名对象。

"hello".equals(str)    一个字符串能够调用一个函数,可以看出,一个字符串是String的匿名对象。

二、比较

(1)直接赋值

String str = “abc”;表示一个堆内存指向给了栈内存。

直接赋值可以节省内存,因为这种情况只要变量不改变就不会重新开辟新的内存空间。


举例:

public class StringDemo01{
    public static void main(String args[]){
       //享元模式
       //在堆内存中有一个"hello"的String对象,而str1和str2和str3指向这个匿名对象
       String str1 ="hello";
       String str2 ="hello";
       String str3 ="hello";
       System.out.println("str1== str2  --> "+(str1 == str2));
       System.out.println("str1== str3  --> "+(str1 == str3));
       System.out.println("str2== str3  --> "+(str2 == str3));
    }
}

运行结果:

str1 == str2  --> true

str1 == str3  --> true

str2 == str3 --> true

 

(2)new


举例:

 public class StringDemo02{
       public static void main(String args[]){
             
              String str1 = new String("hello");
              String str2 = new String("hello");
              System.out.println("str1==str2-->"+(str1==str2));
       }
}

运行结果:

str1==str2-->false

 分析:

1.创建了"hello"的匿名String对象。

2.创建一个str的对象,并开辟新的堆空间。

3.原来的“hello”的匿名对象变成垃圾。

 总结:第二种每new一次都会开辟新的内存空间,要不是特殊需要不建议这样做,因此开发中最好使用直接赋值。

三、字符串的不可改变性

看上图:为什么str+="world"这种连接操作效率低,就是因为这个。

所以才会有StringBuilder或者StringBuffer。下面就比较一下它们的性能:

四、String、StringBuilder和StringBuffer的性能比较

请看下面的例子:

public static void main(Stringargs[]){
      long begin1 = System.currentTimeMillis();
      String str = "";
      for(int i=0;i<10000;i++){
         str+=i;
      }
      long end1 = System.currentTimeMillis();
      System.out.println("String用时: "+(end1-begin1)+" ms"); //用时906ms
     
      long begin2 = System.currentTimeMillis();
      StringBuilder sbuilder = new StringBuilder();
      for(int i=0;i<10000;i++){
         sbuilder.append(i);
      }
      long end2 = System.currentTimeMillis();
      System.out.println("StringBuilder用时: "+(end2-begin2)+" ms");   //用时0ms,所以快了很多
     
      long begin3 = System.currentTimeMillis();
      StringBuffer stringBuffer = new StringBuffer();
      for(int i=0;i<10000;i++){
         stringBuffer.append(i);
      }
      long end3 = System.currentTimeMillis();
      System.out.println("stringBuffer用时: "+(end3-begin3)+" ms"); //用时0ms,所以快了很多
   }

运行结果:

String用时: 906 ms

StringBuilder用时: 0 ms

stringBuffer用时: 0 ms

 

总结:

        从例子中可以看出,三种方法后两种的效率远高于第一种,所以当我们又大量循环拼接字符串的时候就应该首先考虑它的效率问题,选择后两种方法。

        写代码都是为了得到最后的运行结果,而想要得到运行结果会遇到最大问题就是要控制其在最短的时间内执行完,所以我们写代码的时候一定要考虑效率问题,不能只为实现功能而写。那怎么才能做到写出即实现功能又能高效执行的代码,我觉得现在至少可以先从三方面入手,第一:实现了一个功能的代码要回去多看看,有没有可以优化的地方,不要实现了就万事大捷,再也不管了,那样最后优化人员可能会把你写的代码改的面目全非。第二、多看高手写的代码,和自己的想法对比学习。第三、多思考,多看网上的优秀博客,尤其优化方面的博客,很多都是谈的效率问题。

 

抱歉!评论已关闭.