(二十六)String、StringBuffer、StringBuilder、StringTokenizer区别
一、String 和 StringBuffer:
(二十六.1)java String 在内存中如何存储的?
①String类型和StringBuffer类型的主要性能区别:String是不可变的对象,因此每次在对String类进行改变的时候都会生成一个新的string对象,然后将指针指向新的string对象,所以经常要改变字符串长度的话不要使用string,因为每次生成对象都会对系统性能产生影响,特别是当内存中引用的对象多了以后,JVM的GC就会开始工作,性能就会降低;
String s="Hello";
s+="World";
在这段代码中,s原先指向一个String对象,内容是hello,然后我们对s进行+操作,那么s所指向的那个对象是否发生了变化呢?答案是没有,这时,s不再指向原来的那个对象了,而指向另一个String对象,内容为hello world ,原来的那个对象还存在于内存中(没有人用它的话会被回收),只是s这个引用变量不再指向它了。
②使用StringBuffer类时,每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象引用,所以多数情况下推荐使用StringBuffer,特别是字符串对象经常要改变的情况;
③在某些情况下,String对象的字符串拼接其实是被Java Compiler编译成了StringBuffer对象的拼接,所以这些时候String对象的速度并不会比StringBuffer对象慢.
String字符串修改实现的原理如下:
当用String类型来对字符串进行修改的时候,其实现方法是首先创建一个StingBuffer,其次再调用StingBuffer的append()方法,最后调用StringBuffer的toString()方法把结果返回。
示例如下:
String s="Hello";
s+="World";
//等价于
StringBuffer s1=new StringBuffer(s);
s1.append("World");
s=s1.toString();
由此可以看出,上述过程比使用StringBuffer多了一些附加的操作,同时也生成了一个临时的对象,
从而导致程序的执行效率降低。
④String与StringBuffer的另外一个区别在于当实例化String的时候,可以利用构造函数(String s1=new Sting("world"))的方式来对其进行初始化,也可以用赋值(String s="Hello")的方式来初始化,而StingBuffer只能使用构造函数(StringBuffer s=new StringBuffer("Hello"))的方式来初始化。
二、StringBuilder
StringBuilder也是可以被修改的字符串,它与StringBuffer类似,都是字符串缓冲区,但是StringBuilder不是线程安全的。
因此,如果只在单线程中使用字符串缓冲区,使用StringBuilder的效率会高一些。
而当多个线程访问的时候,最好使用线程安全的StringBuffer,因为StringBuffer必要时可以对这些方法进行同步,所以任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
三、String、StringBuffer、StringBuilder如何选择
执行效率StringBuilder>StringBuffer>String
使用 String 类的场景:在字符串不经常变化的场景中可以使用 String 类,例如常量的声明、少量的变量运算。
使用 StringBuffer 类的场景:在频繁进行字符串运算(如拼接、替换、删除等),并且运行在多线程环境中,则可以考虑使用 StringBuffer,例如 XML 解析、HTTP 参数解析和封装。
使用 StringBuilder 类的场景:在频繁进行字符串运算(如拼接、替换、和删除等),并且运行在单线程的环境中,则可以考虑使用 StringBuilder,如 SQL 语句的拼装、JSON 封装等。
四、StringTokenizer
是用来分割字符串的工具类
https://www.cnblogs.com/gaopeng527/p/4899237.html
参考:
https://www.jianshu.com/p/8c724dd28fa4
https://www.smwenku.com/a/5c0ac135bd9eee6fb37bf3c2/zh-cn