JAVA:构建字符串StringBuffer(一)

【1】构建字符串的方法

  • 方法一:字符串的连接方式
  • 对于字符串而言我们经常是要对其进行拼装处理的,在java中提高了三种拼装的方法:+、concat()以及append()方法。这三者之间存在什么区别呢?先看如下示例:
public class StringTest {

    /**
     * @desc 使用+、concat()、append()方法循环10W次
     * @author chenssy
     * @data 2013-11-16
     * @param args
     * @return void
     */
    public static void main(String[] args) {
        //+
        long start_01 = System.currentTimeMillis();
        String a = "a";
        for(int i = 0 ; i < 100000 ; i++){
            a += "b";
        }
        long end_01 = System.currentTimeMillis();
        System.out.println("  +   所消耗的时间:" + (end_01 - start_01) + "毫米");

        //concat()
        long start_02 = System.currentTimeMillis();
        String c = "c";
        for(int i = 0 ; i < 100000 ; i++){
            c = c.concat("d");
        }
        long end_02 = System.currentTimeMillis();
        System.out.println("concat所消耗的时间:" + (end_02 - start_02) + "毫米");

        //append
        long start_03 = System.currentTimeMillis();
        StringBuffer e = new StringBuffer("e");
        for(int i = 0 ; i < 100000 ; i++){
            e.append("d");
        }
        long end_03 = System.currentTimeMillis();
        System.out.println("append所消耗的时间:" + (end_03 - start_03) + "毫米");
    }
}

------------
Output:
 +   所消耗的时间:19080毫米
concat所消耗的时间:9089毫米
append所消耗的时间:10毫米
  • 从上面的运行结果可以看出,append()速度最快,concat()次之,+最慢。原因请看下面分解:
  • (一)+方式拼接字符串
    在前面我们知道编译器对+进行了优化,它是使用StringBuilder的append()方法来进行处理的,我们知道StringBuilder的速度比StringBuffer的速度更加快,但是为何运行速度还是那样呢?主要是因为编译器使用append()方法追加后要同toString()转换成String字符串,也就说 str +=”b”等同于
    str = new StringBuilder(str).append(“b”).toString();
    它变慢的关键原因就在于new StringBuilder()和toString(),这里可是创建了10W个StringBuilder对象,而且每次还需要将其转换成String,速度能不慢么?
  • (二)concat()方法拼接字符串
public AbstractStringBuilder append(String str) {
    if (str == null) str = "null";
        int len = str.length();
    if (len == 0) return this;
    int newCount = count + len;
    if (newCount > value.length)
        expandCapacity(newCount);
    str.getChars(0, len, value, count);
    count = newCount;
    return this;
    }
  • 这是concat()的源码,它看上去就是一个数字拷贝形式,我们知道数组的处理速度是非常快的,但是由于该方法最后是这样的:return new String(0, count + otherLen, buf);这同样也创建了10W个字符串对象,这是它变慢的根本原因。

  • (三)append()方法拼接字符串

public synchronized StringBuffer append(String str) 
{
    super.append(str);
    return this;
}
  • StringBuffer的append()方法是直接使用父类AbstractStringBuilder的append()方法,该方法的源码如下:
public AbstractStringBuilder append(String str)
 {
    if (str == null) str = "null";
        int len = str.length();
    if (len == 0) return this;
    int newCount = count + len;
    if (newCount > value.length)
        expandCapacity(newCount);
    str.getChars(0, len, value, count);
    count = newCount;
    return this;
  }
  • 与concat()方法相似,它也是进行字符数组处理的,加长,然后拷贝,但是请注意它最后是返回并没有返回一个新串,而是返回本身,也就说这这个10W次的循环过程中,它并没有产生新的字符串对象。

  • 通过上面的分析,我们需要在合适的场所选择合适的字符串拼接方式,但是并不一定就要选择append()和concat()方法,原因在于+根据符合我们的编程习惯,只有到了使用append()和concat()方法确实是可以对我们系统的效率起到比较大的帮助,才会考虑。

    以上内容转自:http://blog.csdn.net/chenssy/article/details/17591363

  • 方法二:使用StringBuffer类
  • 方法二:使用Stringbuilder类

【2】使用StringBuffer类

【2-1】StringBuffer类的介绍

  • 回忆一下String类:String类对象的内容是可以被再改变的。String类用于比较、查找和抽取串中的字符或字符串、字符串与其他类型之间的相互转换等。
  • 在Java中规定,一旦声明String的内容就不可再改变,如果改变,也改变的是String的引用地址。如果一个字符串需要经常被改变,则必须使用StringBuffered类。
  • StringBuffer类:用于对象内容可以改变的字符串,可以将其他各种类型的数据增加、插入到字符串中,也可以翻转字符串原来的内容。在修改时StringBuffer都是修改自身(不会产生一个新的字符串对象),而String类则是产生一个新的对象,这是他们之间最大的区别。
  • 一旦通过StringBuffer生成了最终想要的字符串,就应该使用StringBuffer.toString方法将其转换成String类。之后,就可以使用String类的各种方法操作这个字符串了。
  • 有一个最显著的区别在于,对于StringBuffer对象的每次修改都会改变对象自身,这点是和String类最大的区别。另外由于StringBuffer是线程安全的,所以在多线程程序中也可以很方便的进行使用,但是程序的执行效率相对来说就要稍微慢一些。
StringBuffer str = new StringBuffer("abde");
String strTest = str.toString();
  • Java提供了特别的连接字符串操作符(+),可以把其他各种类型的数据转换成字符串,并前后连接成新的字符串。连接操作的功能就是通过StringBuffer类和它的append方法实现的。
StringBuffer str = new StringBuffer("abde").append("zhongguo");
String strTest = str.toString();
String str = new StringBuffer().append("ab").append("中国").append(1123).to.String();

【2-2】StringBuffer类的构造方法

  • StringBuffer类是不能通过字面量进行初始化,必须要产生一个StringBuffer实例,也就是必须通过它的构造方法进行初始化。
package he.qiang;
import java.lang.String;

public class StringTest 
{
    public static void main(String[] args) 
    {
        StringBuffer strr = "hdede";
    }
}

JAVA:构建字符串StringBuffer(一)_第1张图片

  • 构造方法StringBuffer( )
    —–Constructs a string buffer with no characters in it and an initial capacity of 16 characters.默认的长度的16字符
//创建一个不带内容的StringBuffer对象:
StringBuffer str = new StringBuffer();
//创建一个StringBuffer对象str,且该对象初始化为一个空的对象。
  • 构造方法StringBuffer(String str)
    —–Constructs a string buffer initialized to the contents of the specified string.
//创建一个带内容的StringBuffer对象:
StringBuffer str = new StringBuffer("china");
//创建一个StringBuffer对象str,且该对象的内容被初始化为"china"。
  • 构造方法StringBuffer(CharSequence seq)
    —–Constructs a string buffer that contains the same characters as the specified CharSequence.

  • 构造方法StringBuffer(int capacity)
    —–Constructs a string buffer with no characters in it and the specified initial capacity.

package he.qiang;
import java.lang.String;

public class StringTest 
{
    public static void main(String[] args) 
    {
        StringBuffer str1 = new StringBuffer();
        StringBuffer str2 = new StringBuffer(10);
        StringBuffer str3 = new StringBuffer(20);

        System.out.println(str1.capacity());//运行结果:16
        System.out.println(str2.capacity());//运行结果:10
        System.out.println(str3.capacity());//运行结果:20
    }
}
  • String类对象和StringBuffer类对象之间的相互转化
  • 需要注意的是,StringBuffer和String属于不同的类型,也不能直接进行强制类型转换,下面的代码都是错误的:
StringBuffer str = "abc"; //赋值类型不匹配
StringBuffer s = (StringBuffer)str; //不存在继承关系,无法进行强转
  • StringBuffer对象和String对象之间的互转的代码如下:
String s = "abc";
StringBuffer sb2 = new StringBuffer(s); //String转换为StringBuffer

(1)StringBuffer sb1 = new StringBuffer("abc");
(2)String s1 = sb1.toString(); //StringBuffer转换为String
//可以将(1)(2)写合一句:String s1 = new StringBuffer("abc").toString();

【3】StringBuffer类的常用方法

  • 在StringBuffer的使用方面,它更加侧重于对字符串的变化,例如追加、修改、删除,相对应的方法:
    (1)append():追加指定内容到当前StringBuffer对象的末尾,类似于字符串的连接,这里StringBuffer对象的内容会发生改变。
    (2)insert:该类方法主要是在StringBuffer对象中插入内容。
    (3)delete:该类方法主要用于移除StringBuffer对象中的内容。

    以下部分内容转载出处:http://www.cnblogs.com/springcsc/archive/2009/12/03/1616330.html

  • a)append方法:public StringBuffer append(boolean b)
    该方法的作用是将Boolean参数作为内容追加到当前StringBuffer对象的末尾,类似于字符串的连接。调用该方法以后,StringBuffer对象的内容也发生改变,例如:

StringBuffer sb = new StringBuffer("abc");
sb.append(true);
//则对象sb的值将变成"abctrue"。
  • append方法:public StringBuffer append(String str)
    使用该方法进行字符串的连接,将比String更加节约内容,例如应用于数据库SQL语句的连接,例如:
StringBuffer sb = new StringBuffer();
String user = "test";
String pwd = "123";
sb.append("select * from userInfo where username=").append(user).append(" and pwd=").append(pwd);
//这样对象sb的值就是字符串"select * from userInfo where username=test and pwd=123"。
  • b)deleteCharAt方法:public StringBuffer deleteCharAt(int index)
    该方法的作用是删除指定位置的字符,然后将剩余的内容形作为当前实例对象的内容。例如:
StringBuffer sb = new StringBuffer("Test");
sb. deleteCharAt(1);

该代码的作用删除字符串对象sb中索引值为1的字符,也就是删除第二个字符,剩余的内容组成一个新的字符串。所以对象sb的值变为“Tst”

  • 还存在一个功能类似的delete方法:public StringBuffer delete(int start,int end)
    该方法的作用是删除指定区间以内的所有字符,包含start,不包含end索引值的区间。例如:
StringBuffer sb = new StringBuffer("TestString");
sb. delete (1,4);

该代码的作用是删除索引值1(包括)到索引值4(不包括)之间的所有字符,变量sb指向的内容为剩余的字符。则对象sb的值是”TString”。

  • c)insert方法:public StringBuffer insert(int offset, boolean b)
    该方法的作用是在StringBuffer对象中插入内容,然后形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“TestString”);
sb.insert(4,false);

该示例代码的作用是在对象sb的索引值4的位置插入false值,形成新的字符串,则执行以后对象sb的值是”TestfalseString”。

  • d)reverse方法:public StringBuffer reverse()
    该方法的作用是将StringBuffer对象中的内容反转,然后形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.reverse();
//经过反转以后,对象sb中的内容将变为”cba”。
  • e)setCharAt方法:public void setCharAt(int index, char ch)
    该方法的作用是修改对象中索引值为index位置的字符为新的字符ch。例如:
StringBuffer sb = new StringBuffer("abc");
sb.setCharAt(1,'D');
//则对象sb的值将变成"aDc"。
  • f)trimToSize方法:public void trimToSize()
    该方法的作用是将StringBuffer对象的中存储空间缩小到和字符串长度一样的长度,减少空间的浪费。
package he.qiang;
import java.lang.String;

public class StringTest 
{
    public static void main(String[] args) 
    {
        StringBuffer str1 = new StringBuffer();//初始容量是16个字符
        str1.append("abc");

        System.out.println(str1.capacity());

        int strLength = str1.length();
        /*the length of the sequence of characters currently represented by this object*/
        System.out.println(strLength);

        str1.trimToSize();
        System.out.println(str1.capacity());
    }
}

JAVA:构建字符串StringBuffer(一)_第2张图片
- g)substring方法:public String substring(int start)public String substring(int start, int end)
该方法的作用和String类中的substring方法一样。

  • i)subSequence方法:public String subSequence(int start, int end)
    该方法的作用是返回一个新的字符序列,该序列是原StringBuffer对象的子序列。
    JAVA:构建字符串StringBuffer(一)_第3张图片

  • j)indexOf方法、lastIndexOf方法:
    这里写图片描述
    这里写图片描述

  • 总之,在实际使用时,String和StringBuffer各有优势和不足,可以根据具体的使用环境,选择对应的类型进行使用。

你可能感兴趣的:(Java,EE)