`
Java小貔貅
  • 浏览: 28867 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

StringBuffer截取字符串的使用

阅读更多

当我们进行字符拼接时,请使用StringBuffer类而非String类,因为前者将比后者快上百倍。

String str="You are nice.";
str+="I love you so much.";

如果用StringBuffer类的话,代码如下:
StringBuffer str= new StringBuffer("You are nice.");
str.append("I love you so much.");

用法:

StringBuffer sb = new StringBuffer(); sb.append("yacht1") ; sb.append("yacht2"); sb.append("yacht3") ; sb.append("yacht4");     String a = sb.toString();

 

String && StringBuffer的区别:
非可变对象一旦创建之后就不能再被改变,可变对象则可以在创建之后被改变。String对象是非可变对象;StringBuffer对象则是可变对象。为获得更佳的性能需要根据实际情况小心谨慎地选择到底使用这两者中的某一个。

String类用来表示那些创建后就不会再改变的字符串,它是不可变的(immutable);
StringBuffer类用来表示内容可变的字符串;
例:
1.String对象:
String str = "Hello";
str += "World";
//     JVM会创建一个临时的StringBuffer类对象,并调用其append()方法完成字符串的拼接,这是因为 String类是不可变的,拼接操作不得不使用StringBuffer类(并且--JVM会将"Hello"和"World"创建为两个新的 String对象)。之后,再将这个临时StringBuffer对象转型为一个String,代价不菲!可见,在这一个简单的一次拼接过程中,我们让程序创建了四个对象:两个待拼接的String,一个临时StringBuffer,和最后将StringBuffer转型成为的String--它不是最初的str,而是最初的str的引用指向了新生成的String对象"HelloWorld"。
2.StringBuffer对象:
StringBuffer strBuf = new StringBuffer("Hello");
strBuf.append("World");
//     程序将只产生两个对象:最初的strBuf :"Hello"和拼接时的String("World"),不再需要创建临时的StringBuffer类对象而后还得将其转换回String对象。节省额外的系统开销。

如何选择是使用String还是StringBuffer:
取决于两种情况,第一种情况是需要连接的字符串是在编译期决定的还是在运行期决定的,第二种情况是你使用的是StringBuffer还是String。
1) 第一种情况:编译期决定相对于运行期决定;如:
String str = "This " + "is " + "a " + "Java " + "program";
StringBuffer strBuf = new StringBuffer();
strBuf.append("This ");
strBuf.append("is ");
strBuf.append("a ");
strBuf.append("Java ");
strBuf.append("program");

此时,+操作符比StringBuffer.append()方法要快,WHY?这里编译器的优化起了关键作用,编译器简单地在编译期连接多个字符串。它使用编译期决定取代运行期决定,在你使用new关键字来创建String对象的时候也是如此。这里str对象在编译期就决定了而 StringBuffer对象是在运行期决定的。运行期决定需要额外的开销当字符串的值无法预先知道的时候,编译期决定作用于字符串的值可以预先知道的时候,也就是说String str = "This " + "is " + "a " + "Java " + "program";这段代码在编译时,编译器会对程序作出优化,String str被优化成“This is a Java program”;而StringBuffer strBuf只会在运行时才处理。所以效率是不一样的。(注意,这里的String str = "This " + "is " + "a " + "Java " + "program";与 String str = "Hello";
str += "World";是不一样的);
2) 第二种情况:使用StringBuffer取代String
String str = "Hello";
for(int i = 0; i < 40000; i++) {
     str += "World";
}

StringBuffer strBuf = new StringBuffer("Hello");
for(int i = 0; i < 40000; i++) {
      strBuf.append("World");
}
此时,StringBuffer.append()方法要比+操作符快得多,WHY?原因是两者都是在运行期决定字符串对象,但是+操作符使用不同于StringBuffer.append()的规则;它是通过String和StringBuffer来完成字符串的连接操作的。

另外,在使用StringBuffer时,可以通过StringBuffer的构造函数来设定它的初始化容量,这样可以明显地提升性能。这里提到的构造函数是StringBuffer(int length),length参数表示当前的StringBuffer能保持的字符数量。如:
(1)
StringBuffer strBuf = new StringBuffer();
             for(int i = 0; i < 40000; i++) {
                  strBuf.append("Hello");
             }
(2)
StringBuffer strBuf = new StringBuffer(100000);
             for(int i = 0; i < 40000; i++) {
                  strBuf.append("Hello");
             }
此时,(2) 的效率好于 (1),因为StringBuffer内部实现是char数组,当使用缺省的构造函数来创建StringBuffer对象的时候,因为没有设置初始化字符长度,StringBuffer的容量被初始化为16个字符,也就是说缺省容量就是16个字符。当StringBuffer达到最大容量的时候,它会将自身容量增加到当前的2倍再加2,也就是(2*旧值+2)。 如果使用缺省值,初始化之后接着往里面追加字符,在追加到第16个字符的时候它会将容量增加到 34(2*16+2),当追加到34个字符的时候就会将容量增加到70(2*34+2)。无论何事只要StringBuffer到达它的最大容量它就不得不创建一个新的字符数组然后重新将旧字符和新字符都拷贝一遍。所以总是给StringBuffer设置一个合理的初始化容量值是错不了的,这样会带来立竿见影的性能增益。(2)避免了复制数组的开销。

创建String对象:
String str = "Hello";
//   JVM先根据内容"Hello"查找对象,如果没找到,则在heap(堆栈)*上创建新对象,并将其赋予str,否则使用已经存在的对象。

String str = new String("Hello");
//   据内不管heap上有没有"Hello"这个对象,JVM都会在heap上创建一个新String对象;此时heap上可能会出现内容相同,地址不同的String对象。
推荐使用String str = "Hello";这种方法创建String类型的对象,这样会使heap中只存在唯一的一个存放"Hello"对象的内存地址;实际上我们不需要多个独立的"Hello"对象,因为要运行它们的话浪费时间+浪费内存。我们也不必因使用new String("Hello");创建了多个”Hello”对象而发愁,可以使用intern()方法来避免在堆内存上创建重复的String对象来改善Java的运行性能。String intern()方法检查字符串对象的存在性,如果需要的字符串已经存在,那么它将会引用指向已经存在的字符串对象而不是重新创建一个。这和使用 String str = "Hello";这种方法创建对象就作用上来说是一致的。使用intern():
String str = new String("Hello");
str = str.intern();

String对象的比较:
"=="            //比较地址;
"equals"    //比较内容;

String str1 = "a";
String str2 = "a";
String str3 = new String("a");
str1 == str2        //    true
str1 == str3        //    false
str1.equals(str2);       //   true
str1.equals(str3);       //   true

但是StringBuffer类并没有实现Objcet类的Equals方法,所以不能用这个方法来比较两个StringBuffer类的字符串是否相等:
StringBuffer strBuf1 = new StringBuffer(“a”);
StringBuffer strBuf2 = new StringBuffer(“a”);
     System.out.println(
strBuf1.equals(strBuf2
));
程序输出:false

*这里想对“heap(堆栈)”做一下更正:应该是heap(堆),而非堆栈。
“堆”是一种通用的内存池,用于存放所有的Java对象。当使用“new”实例化一个对象时,编译器会自动在堆里进行存储分配。
C++在堆栈中创建对象,Java对象引用存储在堆栈中;而Java对象并不存储于其中。
堆栈:堆栈指针向下移动,分配新内存,向上移动,释放内存;创建程序时编译器必须知道存储在堆栈中所有数据的确切大小和生命周期,因为要通过代码实现来控制上下移动堆栈指针,这一约束限制了程序的灵活性。而如果是在堆上创建对象,编译器不需要知道从堆里分配多少存储区域,也不必知道存储的数据在堆里存活多长时间。因此,在堆里分配存储有很大的灵活性。

分享到:
评论

相关推荐

    js截取字符串

    js截取字符串常用的方法很多,你知道多少呢?看看String和StringBuffer如何截取字符串的

    StringBuffer总结

    StringBuffer的特点,Stringbuffer是字符串缓冲区: 是一个容器。

    java字符串操作大全

     (6)、append() 可把任何类型数据的字符串表示连接到调用的StringBuffer对象的末尾。  例:int a=42;  StringBuffer sb=new StringBuffer(40);  String s=sb.append("a=").append(a).append("!").toString();...

    java实验-字符串.docx

    编写程序完成如下功能:输出字符串“www.google.com”的长度,并分别计算并显示出‘o’ 与‘g’的个数,截取其中“google”进行输出显示。...3、分别使用String和StringBuffer类实现字符串的链接,分析比较它们的特点。

    Java的String类讲解案例代码(String类使用:创建对象、比较、连接、截取、查找和替换、拆分...)StringBuf

    String类使用(创建字符串对象、比较、长度、连接、截取、查找和替换、切割和拆分、和其他类型的转换、格式化、判断、手动入池、其他操作) StringBuffer类 StringBuilder类 String、StringBuffer和StringBuilder的...

    Java中常用字符串方法总结

     1、使用字符串常量直接初始化 String s=hello!;  2、使用构造方法创建并初始化 String();//初始化一个对象,表示空字符序列  String(value);//利用已存在的字符串常量创建一个新的对象  String (char[] ...

    java初学者必看

    5.1.3 StringBuffer创建字符串 5.2 连接字符串 5.2.1 与字符串的连接 5.2.2 与其他数据类型的连接 5.3 String字符串操作 5.3.1 基本操作 5.3.2 比较 5.3.3 转化 5.3.4 查找 5.3.5 截取拆分 5.3.6 替换或...

    Java范例开发大全 (源程序)

     6.2 字符串缓存类StringBuffer 143  实例106 创建字符串缓存类 143  实例107 提取单个字符 144  实例108 给指定字符赋值 145  实例109 插入新的字符 146  实例110 插入新的字符串 146  实例111 获取...

    java范例开发大全(pdf&源码)

    6.2 字符串缓存类StringBuffer 143 实例106 创建字符串缓存类 143 实例107 提取单个字符 144 实例108 给指定字符赋值 145 实例109 插入新的字符 146 实例110 插入新的字符串 146 实例111 获取字符串的子串 147 实例...

    java范例开发大全源代码

     6.2 字符串缓存类StringBuffer 143  实例106 创建字符串缓存类 143  实例107 提取单个字符 144  实例108 给指定字符赋值 145  实例109 插入新的字符 146  实例110 插入新的字符串 146  实例111 ...

    java范例开发大全

    6.2 字符串缓存类StringBuffer 143 实例106 创建字符串缓存类 143 实例107 提取单个字符 144 实例108 给指定字符赋值 145 实例109 插入新的字符 146 实例110 插入新的字符串 146 实例111 获取字符串的子串 147 实例...

    Java范例开发大全(全书源程序)

    6.2 字符串缓存类StringBuffer 143 实例106 创建字符串缓存类 143 实例107 提取单个字符 144 实例108 给指定字符赋值 145 实例109 插入新的字符 146 实例110 插入新的字符串 146 实例111 获取字符串的子串 ...

    千方百计笔试题大全

    56、写一个函数,要求输入一个字符串和一个字符长度,对该字符串进行分隔。 14 59、Java 编程,打印昨天的当前时刻。 15 60、java 和javasciprt 的区别。 15 61、什么时候用assert? 16 62、error和exception有什么...

    java面试宝典

    56、写一个函数,要求输入一个字符串和一个字符长度,对该字符串进行分隔。 14 59、Java 编程,打印昨天的当前时刻。 15 60、java 和javasciprt 的区别。 15 61、什么时候用assert? 16 62、error和exception有什么...

    最新Java面试宝典pdf版

    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...

    Java面试笔试资料大全

    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...

    Java面试宝典2010版

    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...

    jsp网络编程从基础到实践

    实例8 查找字符串程序示例 实例9 StringBuffer综合应用程序示例 实例10 日期数据应用示例 实例11 算术表达式综合运用实例 实例12 switch语句示例 实例13 循环应用综合实例 实例14 一个简单的计数器 实例15 ...

    JSP网络编程从基础到实践 实例代码

    实例8 查找字符串程序示例 实例9 StringBuffer综合应用程序示例 实例10 日期数据应用示例 实例11 算术表达式综合运用实例 实例12 switch语句示例 实例13 循环应用综合实例 实例14 一个简单的计数器 实例15 ...

    Java面试宝典-经典

    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...

Global site tag (gtag.js) - Google Analytics