String、StringBuilder、StringBuffer的爱恨情仇

独火星
• 阅读 972

第三阶段 JAVA常见对象的学习

StringBuffer和StringBuilder类

(一) StringBuffer类的概述

(1) 基本概述

下文以StringBuffer为例

前面我们用字符串做拼接,比较耗时并且也耗内存(每次都会构造一个新的string对象),而这种拼接操作又是比较常见的,为了解决这个问题,Java就提供了两个字符串缓冲区类。StringBuffer和StringBuilder供我们使用。

简单比较:

String 长度大小不可变

StringBuffer 长度可变、线程安全、速度较慢

StringBuilder 长度可变、线程不安全、速度最快

-----------------------------------------------------------------------------------------------------------------

解释:

  1. 在执行速度方面的比较:StringBuilder > StringBuffer
  2. StringBuffer与StringBuilder,他们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,不像String一样创建一些对象进行操作,所以速度就快了。
  3. StringBuilder:线程非安全的

    StringBuffer:线程是安全的(synchronized关键字进行修饰)

当我们在字符串缓冲区被多个线程使用时,JVM不能保证StringBuilder的操作是安全的,虽然他的速度最快,但是可以保证StringBuffer是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用StringBuilder而不用StringBuffer的,就是速度的原因。

对于三者使用的总结:

1.如果要操作少量的数据用 = String
2.单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
3.多线程操作字符串缓冲区 下操作大量数据 = StringBuffer

(2) StringBuffer的构造方法
//无参构造方法
StringBuffer()
    
//指定容量的字符串缓冲区对象
StringBuffer(int size)
    
//指定字符串内容的字符串缓冲区对象
StringBuffer(String str)

(二) StringBuffer 类的功能

(1) 添加功能
//可以把任意类型添加到字符串缓冲区里,并且返回字符串缓冲区本身(this)
public StringBuffer append (String str)

//在offset位置把任意类型的数据插入到字符串缓冲区中,并且返回字符串缓冲区本身(this)
public StringBuffer insert(int offset,String str)
(2) 删除功能
//删除指定位置的字符,并且返回本身
public StringBuffer deleteCharAt(int index)

//删除从指定位置开始指定位置结束的内容,并且返回本身
public StringBuffer delete(int start, int end) 
(3) 替换功能
//从start到end用str代替
public StringBuffer replace(int start,int end,String str)
(4) 反转功能
//Eg: 好你界世 → 世界你好
public StringBuffer reverse()
(5) 截取功能
//从start位置开始截取,取以后字符串,但不返回本身,原数据不影响
public String substring(int start)

//截取start到end之间的字符串
Publci Stirng substring(int start, int end)

(三) String 和 StringBuffer 类相互转换

(1) 转换原因:

String → StringBuffer 是为了使用后者的功能

StringBuffer → String 可能需要后者的类型

(2) 转换方式

※ String → StringBuffer

String s = “Hello”

//通过构造方法
StringBuffer a = new StringBuffer(s);

//通过append()方法

StringBuffer a = new StringBuffer();
a.append(s);

※ StringBuffer → String

StringBuffer buffer = new StringBuffer(“java”)

//通过构造方法
String str = new String (buffer);

//通过toString()方法
String str = buffer.toString();

(四) “+” 和 StringBuilder 类的爱恨情仇

首先java并不支持运算符重载。

(String类中的 “+”“+=”是java中仅有的两个重载过的运算符)

所以我们可以通过“+”符号 将多个字符串进行拼接

将这段代码利用 javap -c filename 反编译

我们可以看到代码被编译器自动优化成使用StringBuilder方式拼接

运行效率得到了保证

String、StringBuilder、StringBuffer的爱恨情仇

下面一个案例 数组拼接成指定格式的字符串 代码中使用了循环语句

//在循环中通过String拼接字符串
public class StringBuilderDemo {
   public static void main(String[] args) {
       String[] arr = {"Hello", "World", "!!!"};
       String s1 = arrayToString(arr);
       System.out.println(s1);
   }

   public static String arrayToString(String[] arr) {
       String s = "";

       s += "[";
       for (int x = 0; x < arr.length; x++) {
           if (x == arr.length - 1) {
               s += arr[x];
           } else {
               s += arr[x];
               s += ", ";
           }
       }
       s += "]";
       return s;
   }
}
//运行结果
[Hello, World, !!!]

使用String方式进行拼接,我们反编译可以看到,StringBuilder被创建在循环的内部,这意味着每循环一次就会创建一次StringBuilder对象,这可是一个糟糕的事情。

String、StringBuilder、StringBuffer的爱恨情仇

//在循环中使用StringBuilder拼接字符串
public class StringBuilderDemo2 {
    public static void main(String[] args) {
        String[] arr = {"Hello", "World", "!!!"};
        String s1 = arrayToString(arr);
        System.out.println(s1);
    }

    public static String arrayToString(String[] arr) {
        StringBuilder s = new StringBuilder();
        s.append("[");
        for (int x = 0; x < arr.length; x++) {
            if (x == arr.length - 1) {
                s.append(arr[x]);
            } else {
                s.append(arr[x]);
                s.append(", ");
            }
        }
        s.append("]");
        return s.toString();
    }
}
//运行结果
[Hello, World, !!!]

使用StringBuilder方式进行拼接,反汇编代码,可以看到,不仅循环部分的代码更为简洁,而且它只生成了一个StringBuilder对象。显式的创建StringBuilder对象还允许你预先为其指定大小。可以避免多次重新分配缓冲。

总结:

如果字符串操作比较简单,就可以使用“+”运算符操作,编译器会为你合理的构造出最终的字符串结果

如果使用循环语句 最好自己手动创建一个StringBuilder对象,用它来构最终结果

结尾:

如果内容中有什么不足,或者错误的地方,欢迎大家给我留言提出意见, 蟹蟹大家 !^_^

如果能帮到你的话,那就来关注我吧!(系列文章均会在公众号第一时间更新)

在这里的我们素不相识,却都在为了自己的梦而努力 ❤

一个坚持推送原创Java技术的公众号:理想二旬不止

String、StringBuilder、StringBuffer的爱恨情仇

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
4年前
String、StringBuffer、StringBuilder的区别
String字符串常量StringBuffer字符串变量(线程安全)StringBuilder字符串变量(非线程安全) 简要的说,String类型和StringBuffer类型的主要性能区别其实在于String是不可变的对象,因此在每次对String类型进行改变的时候其实都等同于生成了一个新的String
Wesley13 Wesley13
4年前
java中如何处理高并发
1 从最基础的地方做起,优化我们写的代码,减少必要的资源浪费。 a、避免频繁的使用new对象,对于整个应用只需要存在一个实例的类,我们可以使用单例模式。对于String连接操作,使用StringBuffer或StringBuilder,对于工具类可以通过静态方法来访问。 b、避免使用错误的方式,尽量不用instanceof做条件判断。使用java
Wesley13 Wesley13
4年前
java基础学习_常用类小结
看看下面的类,是否都熟悉,简要说明每个类主要是干什么呢?Object:是类层次结构的根类,所有类都直接或者间接的继承自该类。Scanner:获取键盘录入数据的类。String:针对字符串的常见操作的类。StringBuffer/StringBuilder:字符串缓冲区类,提高字符串的操
Easter79 Easter79
4年前
String
一,String,StringBuffer,StringBuilder三者之间的关系三个类的关系:StringBuffer和StringBuilder都继承自AbstractStringBuilder这个类,而AbstractStringBuilder和String都继承自Object这个类(Object是所有java类的超类)
Easter79 Easter79
4年前
String Builder 源码分析
!(https://oscimg.oschina.net/oscnet/2af3de6213a842a08f7a8b1544c6ebf0.png)StringBuilder与StringBuffer区别StringBuilder可变字符串,线程不太安全,但效率高,推荐使用。StringBuffer可变字符串,线程安全,但效率
Easter79 Easter79
4年前
StringBuffer类
父类:java.lang.Objectjava.lang.StringBuffer1.StringBuffer构造方法1StringBuffer()  构造一个不带字符的字符缓冲区,其初始容量为16个字符2StringBuffer(CharSequenceseq)  构造一个字符串缓冲区包含与接口CharSequence相同的字
Easter79 Easter79
4年前
String的相关类和方法
String的相关类和方法一、String,StringBuilder,StringBuffer三者的区别这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面1、运行速度:StringBuilderStringBufferStringString为字符串常量,而StringBuilder和StringBuffe
Wesley13 Wesley13
4年前
Java深究之String、StringBuffer、StringBuilder的区别
       在Java学习中,String、StringBuffer、StringBuilder三者是很重要的,在编写代码中经常使用到他们,那么深入的了解他们的异同是非常重要的,接下里我们详细剖析下这三个的异同之处_首先总结下这三者的区别:_1.基本区别String的对象不可变,StringBuffer和StringBuild
Wesley13 Wesley13
4年前
Java面试中遇到的坑【填坑篇】
1.StringBuilder替代String拼接,面试中经常会问到String,StringBuilder,StringBuffer的区别。!(https://oscimg.oschina.net/oscnet/up3341caf385f4fda1bfbcc15694832b4e.png)!
Stella981 Stella981
4年前
BATJ的常见java面试题
JAVA基础1.JAVA中的几种基本数据类型是什么,各自占用多少字节。2.String类能被继承吗,为什么。不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变。3.String,Stringbuffer,StringBuilder的区别。String字符串常量StringBuffer
为什么idea建议使用“+”拼接字符串 | 京东云技术团队
前言各位小伙伴在字符串拼接时应该都见过下面这种提示:内容翻译:报告StringBuffer、StringBuilder或StringJoiner的任何用法,这些用法可以用单个java.lang.String串联来替换。使用字符串串联可以使代码更短、更简单。
独火星
独火星
Lv1
北风其凉,雨雪其雾。惠而好我,携手同行。
文章
3
粉丝
0
获赞
0