String/StringBuffer/StringBuilder

String,StringBuffer,StringBuilder

String

  1. 被final修饰,不可覆写
  2. 通过字符串数组保存字符
  3. 字符串更新操作不是在原有字符串上进行
  4. 创建字符串的区别
    String str = "Hello World";编译期间会在常量池创建字符串常量以及引用,会检查是否已经存在,避免重复创建
    String str = new String("Hello World")运行期间在堆上创建字符串,不会检查是否已经存在

    /**
     * 比较两种创建字符串方式
     */
    public void testCreateString(){
        String s1 = "Hello World!";
        String s2 = new String("Hello World!");
        String s3 = "Hello World!";
        String s4 = new String("Hello World!");
        System.out.println("\n=====测试创建String方式(相同内容String)=====");
        System.out.println("常量池对象与堆对象引用是否相同:" + (s1 == s2));
        System.out.println("常量池对象引用是否相同:" + (s1 == s3));
        System.out.println("堆对象引用是否相同:" + (s2 == s4));
    }
    
    out:
    =====测试创建String方式(相同内容String)=====
    常量池对象与堆对象引用是否相同:false
    常量池对象引用是否相同:true
    堆对象引用是否相同:false

StringBuffer/StringBuilder

与String相同的地方:final修饰,通过字符串数组保存字符
与String不同的地方:操作在原有的字符串上进行的
StringBuffer与StringBuilder的区别:

  1. StringBuffer线程安全,StringBuilder非线程安全
  2. StringBuilder比StringBuffer效率更高

三者关于效率的比较

一般情况下StringBuilder > StringBuffer > String
但是,对于常量字符串直接连接效率是比StringBuilder/StringBuffer的apped操作效率更高的

/**
     * 测试String、StringBuffer、StringBuilder对象连接
     */
    public void testStrAddend(){
        System.out.println("\n=====测试String、StringBuffer、StringBuilder字符串连接=====");
        int time = 30000;
        System.out.println("执行" + time + "次字符串连接操作");
        // String进行time次连接
        long begin = System.currentTimeMillis();
        String string = "";
        for (int i = 0; i <time; i++) {
            string += i;
        }
        long end = System.currentTimeMillis();
        System.out.println(string.getClass().getName() + "进行变量连接操作消耗" + (end - begin) + "ms");

        // String进行time次连接
        begin = System.currentTimeMillis();
        String string1 = "";
        for (int i = 0; i <time; i++) {
            string1 = "Hello" + "World";
        }
        end = System.currentTimeMillis();
        System.out.println(string1.getClass().getName() + "进行常量连接操作消耗" + (end - begin) + "ms");

        StringBuffer stringBuffer = new StringBuffer();
        //StringBuffer进行time次连接
        begin = System.currentTimeMillis();
        for (int i = 0; i <time ; i++) {
            stringBuffer.append(i);
        }
        end = System.currentTimeMillis();
        System.out.println(stringBuffer.getClass().getName() + "进行变量连接操作消耗" + (end - begin) + "ms");

        StringBuilder stringBuilder = new StringBuilder();
        //StringBuilder进行time次连接
        begin = System.currentTimeMillis();
        for (int i = 0; i <time ; i++) {
            stringBuilder.append(i);
        }
        end = System.currentTimeMillis();
        System.out.println(stringBuilder.getClass().getName() + "进行变量连接操作消耗" + (end - begin) + "ms");

        stringBuilder = new StringBuilder();
        //StringBuilder进行time次连接
        begin = System.currentTimeMillis();
        for (int i = 0; i <time ; i++) {
            stringBuilder.append("Hello ").append("World");
        }
        end = System.currentTimeMillis();
        System.out.println(stringBuilder.getClass().getName() + "进行常量连接操作消耗" + (end - begin) + "ms");
    }
    
    out:
    =====测试String、StringBuffer、StringBuilder字符串连接=====
    执行30000次字符串连接操作
    java.lang.String进行变量连接操作消耗2006ms
    java.lang.String进行常量连接操作消耗1ms
    java.lang.StringBuffer进行变量连接操作消耗8ms
    java.lang.StringBuilder进行变量连接操作消耗5ms
    java.lang.StringBuilder进行常量连接操作消耗12ms

参考

  1. 互联网其它博客内容
  2. JavaSE文档

你可能感兴趣的:(String/StringBuffer/StringBuilder)