java StringBuffer和StringBuilder

java StringBuffer和StringBuilder一、前言我们在实际的开发中,如果需要进行字符串的频繁拼接,会出现以下问题:java中的字符串是不可变的,每一次拼接都会产生新字符串。这样会占用大量的方法区内存。造成内存空间的浪费。eg.Strings=”abc”;s+=”hello”;就以上两行代码,就导致在方法区字符串常量池当中创建了3个对象:”abc””hello””abchello”因此引出StringBuffer和StringBuilder可变字符串!二、如何优化StringBuffer和StringBuild

大家好,又见面了,我是你们的朋友全栈君。

一、前言

我们在实际的开发中,如果需要进行字符串的频繁拼接,会出现以下问题:

java中的字符串是不可变的,每一次拼接都会产生新字符串。
这样会占用大量的方法区内存。造成内存空间的浪费。

eg.

String s = "abc";
s += "hello";

就以上两行代码,就导致在方法区字符串常量池当中创建了3个对象:

"abc"
"hello"
"abchello"

因此引出StringBufferStringBuilder可变字符串!

二、如何优化StringBuffer和StringBuilder的性能?

在创建StringBuffer和StringBuilder的时候尽可能给定一个初始化容量。

最好减少底层数组的扩容次数。预估计一下,给一个大一些初始化容量。

关键点:给一个合适的初始化容量。可以提高程序的执行效率。

三、StringBuffer和StringBuilder的区别?

StringBuffer中的方法都有:synchronized 关键字修饰。表示StringBuffer在多线程环境下运行是安全的。

StringBuilder中的方法都没有:synchronized 关键字修饰,表示StringBuilder在多线程环境下运行是不安全的。

  • StringBuffer是线程安全的。
  • StringBuilder是非线程安全的。

四、String为什么是不可变的?

源代码内,String类中有一个 byte[ ] 数组,这个byte[ ]数组采用了 final 修饰,

因为数组一旦创建长度不可变。并且被final修饰的引用一旦指向某个对象之后,不可再指向其它对象,所以String是不可变的!

所以”abc” 无法变成 “abcd”

五、StringBuilder和StringBuffer为什么是可变的呢?

源代码内,StringBuffer和StringBuilder内部实际上是一个 byte[ ]数组,这个byte[]数组没有被final修饰,

StringBuffer和StringBuilder的初始化容量是 16,当存满之后会进行扩容,底层调用了数组拷贝的方法System.arraycopy()。所以StringBuilder和StringBuffer适合于使用字符串的频繁拼接操作。

注意:
StringBuffer和StringBuilder默认初始化容量为16个byte[] 数组

总结

  1. StringBuffer/StringBuilder可以看做 可变长度字符串
  2. StringBuffer/StringBuilder初始化容量 16.
  3. StringBuffer/StringBuilder是完成字符串拼接操作的,方法名:append
  4. StringBuffer是线程安全的。StringBuilder是非线程安全的。
  5. 频繁进行字符串拼接不建议使用“+

六、构造方法

构造方法名
StringBuilder()
StringBuilder(int capacity)
StringBuilder(String str)

eg.

class StringBufferTest{ 
   
    public static void main(String[] args) { 
   
        StringBuffer s1 = new StringBuffer();//创建一个容量为16的StringBuffer对象

        StringBuffer s2 = new StringBuffer("我是中国人");
        System.out.println(s2);

        StringBuffer s3 = new StringBuffer(100);//创建一个容量为100的StringBuffer对象
    }
}

七、方法

方法名 作用
StringBuilder append(char c) 在字符串尾巴追加字符
int capacity() 当前StringBuffer/StringBuilder的容量
char charAt(int index) 返回指定位置的字符
StringBuilder delete(int start, int end) 删除[start, end)范围的字符
StringBuilder deleteCharAt(int index) 删除指定位置的字符
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) 将字符串转换成char复制到dst数组中
int indexOf(String str) 返回str第一次出现的位置
int lastIndexOf(String str) 返回str最后一次出现的位置
StringBuilder insert(int offset, char c) 在offset位置插入字符
int length() 返回字符串长度
StringBuilder replace(int start, int end, String str) 将[start, end)的内容替换成str
StringBuilder reverse() 字符串翻转
void setCharAt(int index, char ch) 将index位置的字符设置为ch
String substring(int start) 从start开始截取字串
String substring(int start, int end) 截取start到end – 1的字符串
void setLength(int newLength) 设置StringBuffer/StringBuilder的长度,默认补空格,并自动扩充容量
CharSequence subSequence(int start, int end) 和substring一样,只不过返回CharSequence

eg.

class StringBufferTest{ 
   
    public static void main(String[] args) { 
   
        StringBuffer s1 = new StringBuffer();

        s1.append("a");
        s1.append("b").append('c').append('d').append('e').append('f').append("f");
        System.out.println(s1);//ab

        System.out.println(s1.capacity());//16

        System.out.println(s1.charAt(2));//c

        //System.out.println(s1.delete(1, 3));//adef

        //System.out.println(s1.deleteCharAt(2));//abdef

        System.out.println(s1.indexOf("c"));//2

        System.out.println(s1.lastIndexOf("f"));//6

        System.out.println(s1.insert(1, 123));//a123bcdeff

        char[] c = new char[20];
        s1.getChars(0, s1.length(), c, 0);
        System.out.println(Arrays.toString(c));//[a, 1, 2, 3, b, c, d, e, f, f, , , , , , , , , , ]

        System.out.println(s1.length());//10

        System.out.println(s1.replace(1, 4, "A"));//aAbcdeff

        //System.out.println(s1.reverse());//ffedcbAa

        s1.setCharAt(1, 'a');
        System.out.println(s1);//aabcdeff

        System.out.println(s1.substring(2));//bcdeff
        System.out.println(s1.substring(2,5));//bcd
        System.out.println(s1.subSequence(1, 3));//ab

        s1.setLength(100);
        System.out.println(s1.length());//100 直接在后面追加空格
        System.out.println(s1.capacity());//100
    }
}

在这里插入图片描述

StringBuffer和StringBuilder构造方法和方法一样!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/160695.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 修改phpstorm的字体样式和大小

    修改phpstorm的字体样式和大小

    2021年10月15日
    56
  • linux常用命令修改文件权限_使用vim在指定目录下创建文件

    linux常用命令修改文件权限_使用vim在指定目录下创建文件chmod  -changefilemodebits:更改文件权限chmod是用来改变文件或者目录权限的命令,但只有文件的属主和超级用户(root)才有这种权限。更改文件权限的2种方式:一、权限字母+操作符表达式二、数字方法(常用)hmod数字权限方法(推进)命令格式:chmod  [数字组合]  文件名chmod[数字组合]目录名-R参数可递归生效(该目录下所有文件或子目录一起改…

    2022年9月12日
    5
  • Spring源码阅读指南_redis编译安装

    Spring源码阅读指南_redis编译安装1.前言:经过多次拉取Spring源码编译失败经历,一下抓取配置编译过程各个软件版本可能有影响因此先做以记录(时间不同也会导致版本出入要注意)Idea:2020.1.1(参考文献博主2019.3.3版本也可)插件:maven(3.6.3)(未用到)Gradle(4.10.3)Kotlin(idea内装)JDK:原机安装1.8版本需要11版本(后续会说明JDK1.8问题)注:流程可能较长,源码拉取编译不易,耐心阅读2.流程2.1抓取Spring源码GITHUB网址:https://gi

    2022年8月12日
    10
  • 向下取整和向上取整的符号_python向上取整函数

    向下取整和向上取整的符号_python向上取整函数向上取整,运算称为Ceiling,用数学符号⌈⌉(上有起止,开口向下)表示,。向下取整,运算称为Floor,用数学符号⌊⌋(下有起止,开口向上)表示。注意,向上取整和向下取整是针对有浮点数而言的;若整数向上取整和向下取整,都是整数本身。四舍五入:更接近自己的整数;把小数点后面的数字四舍五入 即:如被舍去部分的头一位数字小于五,则舍去;如大于等于五,则被保留…

    2025年8月24日
    15
  • 有关SqlDbType.Decimal

    有关SqlDbType.Decimal今天在开发过程中遇到SqlDbType.Decimal类型的参数,返回值却是没有小数位的整数值,郁闷坏了。查了半天资料,原来需要指定小数位。具体书写如下:               cmd.Parameters.Add(“@Percent”,SqlDbType.Decimal).Direction=ParameterDirection.Output;               cm

    2022年7月20日
    14
  • item buffer_addlistener

    item buffer_addlistener当创建DataGrid控件中的项时(不论是在往返行程中还是在将数据绑定到控件时),都会引发ItemCreated事件。ItemCreated事件通常用于控制DataGrid控件中行的内容和外观。当项被数据绑定到DataGrid控件后,将引发ItemDataBound事件。此事件为您提供了在客户端显示数据项之前访问该数据项的最后机会。当引发此事件后,该数据项将被设为空,并且不再

    2022年10月13日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号