String与StringBuffer效率对比

昨天申请了一个LeetCode的账号,先刷了一题最基础的,字符串逆序输出。

我先写出了如下代码:

public class Solution {
    public String reverseString(String s) {
        String rev = "";
        for(int i = s.length()-1; i >= 0; i--){
            rev += s.charAt(i);
        }
        return rev;
    }
}

这份代码在OJ上运行的结果是Time Limit Exceeded,也就是超时了,显然效率太低。

我又改成如下代码,把String类换成StringBuffer类:

public class Solution {
    public String reverseString(String s) {
        StringBuffer rev = new StringBuffer();
        for(int i = s.length()-1; i >= 0; i--){
            rev.append(s.charAt(i));
        }
        return rev.toString();
    }
}

这份代码可以通过,并且用时只有6ms。

为什么String类和StringBuffer类的效率会相差这么多呢?我上网查了资料,主要是以下原因。

String类的对象其实是一个常量,例如String s = "abc"; 那么s其实是一个常量,它的值就是"abc",不能改变。

Java所提供的String操作方法,比如直接进行 ‘+‘ 运算,其实是作了封装,给了使用者能对String对象进行增加或删除的错觉,本质上并不是如此。

当我们执行 s += "def"; 时,并不是说 s 的内容直接由"abc"变为了"abcdef","abc"仍是"abc","def"会被暂时存储到一块新的内存里,然后再开辟一个新的内存空间,把"abc"和"def"拷贝到这个内存空间,然后 s 指向这个新的内存空间。

这个过程其实就是new了一个新的String对象,新对象是"abcdef",s 抛弃了原来的对象,指向了新对象。

由于每次操作都要重新new一个对象,并且占用大量内存,因此String类的效率不高。

那么StringBuffer呢?

StringBuffer对象是一个长度可变的对象,当对StringBuffer的进行增加或删除时,不需要new一个对象,可以动态地修改堆内存。

StringBuffer提供了append方法,在字符串的末尾进行添加。实际上,String类进行 ‘+‘ 运算,就是创建了一个StringBuffer运算,然后调用append进行添加,最后调用toString把StringBuffer转化为String。

显然,String的效率绝对不如StringBuffer了。

可以再看一个直观的测试样例:

    public static void main(String[] args){
        String toappend = "abcdefghijklmnopqrstuvwxyz";//26个字母,用于每次添加
        int times = 20000;//添加20000次
        //使用String类,将26个字母添加20000次
        long start = System.currentTimeMillis();
        String str = "";
        for(int i = 0; i < times; i++){
            str += toappend;
        }
        long end = System.currentTimeMillis();
        System.out.println("String time = " + (end-start)+" ms");
             //使用StringBuffer类,将26个字母添加20000次
        start = System.currentTimeMillis();
        StringBuffer strbuf = new StringBuffer();
        for(int i = 0; i < times; i++){
            strbuf.append(toappend);
        }
        end = System.currentTimeMillis();
        System.out.println("StringBuffer time = " + (end-start)+" ms");
    }

运行结果:

时间: 2024-08-08 01:27:50

String与StringBuffer效率对比的相关文章

java StringBuffer,StringBuilder,String自身连接效率对比

当我们仅仅需要a+b 的时候,两个字符串链接任何方法的效率基本一样,都在0.0001毫秒内就可以完成.不过如果需要1万次,10000万次,就会发现string自身的join速度显著下降 package com.java.lang; public class StringTest { int MAX = 10000; //1万次累加 public String Buffer(){ StringBuffer sb = new StringBuffer(); for(int i = 0; i < MA

一大波Java来袭(四)String类、StringBuilder类、StringBuffer类对比

本文主要介绍String类.StringBuffer类.StringBuilder类的区别  : 一.概述 (一)String 字符串常量,但是它具有不可变性,就是一旦创建,对它进行的任何修改操作都会创建一个新的字符串对象. (二)StringBuffer 字符串可变量,是线程安全的,和StringBuilder类提供的方法完全相同. 区别在于StringBuffer每个方法中前面添加了"synchronized",保证其是线程安全的. (三)StringBuilder 字符串可变量,

(转)String StringBuilder StringBuffer 对比 总结得非常好

来源:http://blog.csdn.net/clam_clam/article/details/6831345 转自:http://www.iteye.com/topic/522167 作者:每次上网冲杯Java时,都能看到关于String无休无止的争论.还是觉得有必要让这个讨厌又很可爱的String美眉,赤裸裸的站在我们这些Java色狼面前了.嘿嘿.... 众所周知,String是由字符组成的串,在程序中使用频率很高.Java中的String是一个类,而并非基本数据类型. 不过她却不是普通

String StringBuilder StringBuffer 对比 总结得非常好

作者:每次上网冲杯Java时,都能看到关于String无休无止的争论.还是觉得有必要让这个讨厌又很可爱的String美眉,赤裸裸的站在我们这些Java色狼面前了.嘿嘿.... 众所周知,String是由字符组成的串,在程序中使用频率很高.Java中的String是一个类,而并非基本数据类型. 不过她却不是普通的类哦!!! [镜头1] String对象的创建       1.关于类对象的创建,很普通的一种方式就是利用构造器,String类也不例外:String s=new String("Hell

java中String和StringBuffer哪个效率高

大多数的网站以及多数的java书上都会说使用StringBuffer类进行字符串"连接"操作是比String类进行连接操作的效率高的,那么真的是这样吗?在这里我们实际自己测试一下,看看他们两个到底谁的效率高,然后从反编译的代码解释原因. 在我的这篇博客:<Java中 "abc" + '/'和"abc" + "/"的区别>中提到了String类的'+'操作是依赖于StringBuilder类的,而JDK API文档中

String StringBuffer StringBuilder 对比

1.StringBuffer是线程安全的,StringBuilder是非线程安全的 2.对String的修改其实是new了一个StringBuilder并调用append方法,然后调用toString返回一个新的String. StringBuffer是在StringBuilder基础上加锁,加锁是一个重量级的操作,需要调用操作系统内核来实现,比较耗时. 因此效率明显有:String<StringBuffer<StringBuilder; 但是这个并不是绝对的,因为JVM会对String进行优

string、stringbuffer、stringbuild的时间性能对比

新手,请不要喷!谢谢! public static void main(String[] args) { //stringbuffer是线程安全的,运行速度快于string,慢于stringbuild,考虑到运行速度快慢选stringbuild,考虑到安全问题用stringbuffer,为何stringbuffer这个看源码吧,很简单的一个单词,区别了stringbuffer和stringbuild,和运用场景 //检测string的运行速度 String str = "0123456789&q

String、StringBuffer和StringBuild的区别

public class Test1 { public static void stringReplace (String text) { text = text.replace('j','i') ; System.out.println(text) ; } public static void stringBufferReplace(StringBuffer text) { text = text.append("c") ; System.out.println(text) ; }

java之String、StringBuffer、StringBuilder

一.String类: ①.构造字符串对象 常量对象:字符串常量对象是用双引号括起的字符序列.例如:"你好"."12.97"."boy"等. 字符串的字符使用Unicode字符编码,一个字符占两个字节 String类较常用构造方法: String  s1 = new String(); String  s2 = new String(String original); String  s3 = new String(char[] a); Strin