zoukankan      html  css  js  c++  java
  • 关于String 和 StringBuffer、StringBuilder

    闲话不多,先看一段代码

    public class test 
    {
      
      public static void main(String[] args) 
      {
        String str1 = "hello";
        //方法1
        String str2 = "hel"+"lo";
        
        //方法2
        String str3 = "hel";
        str3 = str3 + "lo";   
        System.out.println("str1 == str2 :" + (str1 == str2));
        System.out.println("str1 == str3 :" + (str1 == str3));
      }
    }

    结果会是什么呢,你们可以先猜猜

    ---------------------------------------我是分割线----------------------------------------------------

    答案:

    str1 == str2 :true
    str1 == str3 :false

    对于str2,jvm会自动帮你优化成

    str2 = "hello";

    首先,要注意一点,上面程序中的==并不表示比较内容,它们的值是指向对象所在的内存地址,而不是对象本身,而真正的比较内容是用的equal函数。

    那他们相等的缘由,就一定是因为str1与str2所指向的地址。

    当执行String str1 = "hello";

    真正发生的事情,我们并没有声明一个String对象,我们只是声明了一个只能指向String对象的引用变量。所以

    当继续执行String str2 = "hello";(优化后语句)时并不是new的一个字符串,此时并没有第二个对象产生,str2还是指向原来那个对象,也就是,和str1指向同一个对象。

    ok地址相同了,自然返回true

    str3 =str3+"lo";
    实际上是:
    str3 = (new StringBuilder()).append(str3).append("lo").toString();
    显然,str3是new出来的 

    要注意一点的是,String是不可变类,也就是说执行这个语句的时候,并不是说在原来的对象后面加上lo,而是说重新生成了一个新对象"hello",str3成为这个新对象的引用对象,而最重要的问题是,原先的"hel"依然存在。

    好的,现在你一定在想,能不能有个好点的办法?有!

    StringBuffer对象代表一个字符序列可变的字符串,当一个StringBuffer创建后,通过StringBuffer提供的一些方法可以改变这个字符串对的字符序列,一旦通过StringBuffer生产了最终想要的字符串,调用toString()方法即可将其转换为一个String对象

    而StringBuilder是从jdk1.5后出现的,使用基本同StringBuffer,不同点是StringBuffer是线程安全的,但性能略低,StringBuilder反之

    关于其简单的用法,盗用一下李刚老师的疯狂Java讲义里面的代码吧:

    /**
     * Description:
     * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> 
     * <br/>Copyright (C), 2001-2012, Yeeku.H.Lee
     * <br/>This program is protected by copyright laws.
     * <br/>Program Name:
     * <br/>Date:
     * @author Yeeku.H.Lee kongyeeku@163.com
     * @version 1.0
     */
    public class StringBuilderTest
    {
        public static void main(String[] args) 
        {
            StringBuilder sb = new StringBuilder();
            //追加字符串
            sb.append("java");//sb = "java"
            //插入
            sb.insert(0 , "hello "); //sb="hello java"
            //替换
            sb.replace(5, 6, ","); //sb="hello, java"
            //删除
            sb.delete(5, 6);//sb="hellojava" 
            System.out.println(sb);
            //反转
            sb.reverse();//sb="avajolleh"
            System.out.println(sb);
            System.out.println(sb.length()); //输出9
            System.out.println(sb.capacity()); //输出16
            //改变StringBuilder的长度,将只保留前面部分
            sb.setLength(5); //sb="avajo"
            System.out.println(sb);
        }
    }

    还有一个比较有意思的效率的帖子:赞里面的大神 ChDw(米)

    http://topic.csdn.net/t/20050610/10/4072734.html

    最近笔试比较多,刚好和同学讨论的时候(他是Java方向),又聊到一个东西,即有一个很大的程序运行时候,两个申请相同的字符串的String距离比较远的话却又不相等了后来被告知是因为jvm中有一个缓冲区,每次当新生成一个String的时候,他就会在自己的缓冲去里面找,当工程足够大的时候,原先申请的缓冲区里面已经没有之前那个String了,故他们不相等。

    当了解到这些的时候,突然觉得自己思维有点死了,一直没问过自己,当程序很大的话,难道所有申请过的String都会被保留么?这么没逻辑的事情我居然没有怀疑过,有点汗颜

    作者:FreeAquar
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    【UVA1515 算法竞赛入门指南】 水塘【最小割】
    【uva1658 算法竞赛入门经典】海军上将【费用流】
    【UVA11613 训练指南】生产销售规划 【费用流】
    【UVA10079 训练指南】收集者的难题【最大流】
    【LA2531 训练指南】足球联赛 【最大流】
    【LA2957 训练指南】运送超级计算机【二分,最大流】
    「高等数学学习笔记 DAY2」
    「高等数学学习笔记 DAY1」
    「CF1325D Ehab the Xorcist」
    「CF1325C Ehab and Path-etic MEXs」
  • 原文地址:https://www.cnblogs.com/FreeAquar/p/2710758.html
Copyright © 2011-2022 走看看