内容多为最近学习的自我总结,可能有些地方写的不严谨,甚至会有错误的地方,仅供参考,如发现错误敬请指出,谢谢!

灰色字体为补充扩展内容,多为帮助自己理解。



StringBuffer概述:

  线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。

    线程不安全:

        举例:我在银行创建账户会给我银行卡和存折,我在账户中存入200,如果我和另一个人同时各拿着银行卡和存折去取钱,如果信息没有同步,那我们两个都能取出200,这就是线程不安全。
    线程安全:
        线程之间会同步信息(我走你不走,你走我不走)(互斥)。


StringBuffer构造方法:
  StringBuffer() :  
      构造一个其中不带字符的字符串缓冲区,其初始容量为 16 个字符。(容量是可以自动扩容的)

      自己理解 :创建一个空的字符序列(频繁的扩容很耗时)。

  StringBuffer(int capacity)
      构造一个不带字符,但具有指定初始容量的字符串缓冲区。
      自己理解 :创建了一个空的字符序列,容量为capacity。
  StringBuffer(String str)
      构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容。该字符串的初始容量为 16 加上字符串参数的长度。

      自己理解 :创建了容量为 str.length+16容量的字符串序列,里面存储了字符串str。

测试代码:

 //StringBuffer的构造函数
public class StringBufferDemo01 {
public static void main(String[] args) {
//StingBuffer()创建一个不带字符的字符串缓冲区
StringBuffer sb1=new StringBuffer();
//输入字符串长度
System.out.println(sb1.length());//0
//输出字符串容量
System.out.println(sb1.capacity());//16
//StringBuffer(int capacity)构造一个不带字符的指定初始容量的字符串缓冲区
StringBuffer sb2=new StringBuffer(130);
System.out.println(sb2.length());//0
System.out.println(sb2.capacity());//130
//StringBuffer(String str)
StringBuffer sb3=new StringBuffer("zhaoyuan");
System.out.println(sb3.length());//8
System.out.println(sb3.capacity());//24 }
}


添加方法:
append()和insert()可以添加任意类型,基本数据类型和引用数据类型都可以。

append()方法:(重写)

  StringBuffer append(Object obj) 

    追加 Object 参数的字符串表示形式。 
      注:调用的是toString()方法,拼接的是toString方法返回的字符串。

  StringBuffer append(char[] str) 
    将 char 数组参数的字符串表示形式追加到此序列。 
      注:是将数组里的内容进行拼接,而不是调用toString()

  StringBuffer append(boolean b)
    将 boolean 参数的字符串表示形式追加到序列。
  StringBuffer append(char c)
    将 char 参数的字符串表示形式追加到此序列。
  StringBuffer append(char[] str, int offset, int len)
    将 char 数组参数的子数组的字符串表示形式追加到此序列。
  StringBuffer append(CharSequence s)
    将指定的 CharSequence 追加到该序列。
  StringBuffer append(CharSequence s, int start, int end)
    将指定 CharSequence 的子序列追加到此序列。
  StringBuffer append(double d)
    将 double 参数的字符串表示形式追加到此序列。
  StringBuffer append(float f)
    将 float 参数的字符串表示形式追加到此序列。
  StringBuffer append(int i)
    将 int 参数的字符串表示形式追加到此序列。
  StringBuffer append(long lng)
    将 long 参数的字符串表示形式追加到此序列。

  StringBuffer append(String str)
    将指定的字符串追加到此字符序列。
  StringBuffer append(StringBuffer sb)
    将指定的 StringBuffer 追加到此序列中。

注意:在添加int类型数组时,其实是调用了StringBuffer append(Object obj) 方法,拼接的是数组的地址。

问题:StringBuffer的append方法直接修改了对象的值,那为什么还返回的是StringBuffer类型为什么返回值不是void?
StingBuffer对象调用append方法的时候,添加的字符串是添加到自身字符串序列,目的为为了链式编程。

测试代码:

 //StringBuffer的添加功能方法
public class StringBufferDemo_02 {
public static void main(String[] args) {
//append(String str)
StringBuffer sb1=new StringBuffer("Hello");
StringBuffer sb2=sb1.append("World");
System.out.println(sb1);//HelloWorld
System.out.println(sb2);//HelloWorld
System.out.println(sb1==sb2);//true
System.out.println("------------------------------------------");
//链式编程:
byte b = 1;
short s = 10;
int i = 100;
long l = 1000L;
char c = '中';
float f = 1.23f;
double d =3.14;
boolean flag = true;
Object obj = new Student();//在同一个包下我创建的有一个Studnet类
char []arr={'嘿','哈','嘻'};
StringBuffer sb = new StringBuffer();
sb.append(b).append(s).append(i).append(l).append(c).append(f).append(d).append(flag).append(obj).append(arr);
System.out.println(sb);//1101001000中1.233.14trueStudent{name='null', age=0}嘿哈嘻
}

insert()方法:(重写)

  StringBuffer insert(int offset, boolean b)
    将 boolean 参数的字符串表示形式插入此序列中。
  StringBuffer insert(int offset, char c)
    将 char 参数的字符串表示形式插入此序列中。
  StringBuffer insert(int offset, char[] str)   
    将 char 数组参数的字符串表示形式插入此序列中。
  StringBuffer insert(int index, char[] str, int offset, int len)
    将数组参数 str 的子数组的字符串表示形式插入此序列中。
  StringBuffer insert(int dstOffset, CharSequence s)
    将指定 CharSequence 插入此序列中。
  StringBuffer insert(int dstOffset, CharSequence s, int start, int end)
    将指定 CharSequence 的子序列插入此序列中。
  StringBuffer insert(int offset, double d)
    将 double 参数的字符串表示形式插入此序列中。
  StringBuffer insert(int offset, float f)
    将 float 参数的字符串表示形式插入此序列中。
  StringBuffer insert(int offset, int i)
    将 int 参数的字符串表示形式插入此序列中。
  StringBuffer insert(int offset, long l)
    将 long 参数的字符串表示形式插入此序列中。
  StringBuffer insert(int offset, Object obj)
    将 Object 参数的字符串表示形式插入此字符序列中。
  StringBuffer insert(int offset, String str)
    将字符串插入此字符序列中。
      注:添加在序列的最后,插入的索引位置应该是str.length()不用-1。

测试代码:

 package com.cskaoyan.StringBuffer;
//insert方法
public class StringDemo_03 {
public static void main(String[] args) {
StringBuffer sb1=new StringBuffer("world");
sb1.insert(0,"hello ");//hello world
System.out.println(sb1);
sb1.insert(sb1.length(),"!!");
System.out.println(sb1);// hello world!! }
}


删除方法:

StringBuffer delete(int start, int end)
  移除此序列的子字符串中的字符。
  移除此序列的子字符串中的字符。该子字符串从指定的 start 处开始,一直到索引 end - 1 处的字符,如果不存在这种字符,则一直到序列尾部。如果 start 等于 end,则不发生任何更改。
    参数:(包左不包右)
    start - 起始索引(包含)。
    end - 结束索引(不包含)。

StringBuffer deleteCharAt(int index)
  移除此序列指定位置的 char。
  移除此序列指定位置的 char。此序列将缩短一个 char。
    注:如果给定索引处的字符是增补字符,则此方法将不会移除整个字符。如果需要准确处理增补字符,那么可以通过调用   

测试代码:

 public class StringBufferDemo_03 {
public static void main(String[] args) {
StringBuffer sb=new StringBuffer("Hello World!!");
sb.deleteCharAt(0);
System.out.println(sb);//ello World!!
//在删除索引位置后,此序列将缩短一个
StringBuffer sb1=new StringBuffer("Hello World!!");
sb1.deleteCharAt(0).deleteCharAt(1).deleteCharAt(2);
System.out.println(sb1);//el World!!
// public StringBuffer delete(int start,int end) 包左不包右
StringBuffer sb2=new StringBuffer("Hello World!!");
sb2.delete(0,6);
System.out.println(sb2);//World!!
}
}


替换方法:
StringBuffer replace(int start, int end, String str) 

  使用给定 String 中的字符替换此序列的子字符串中的字符。该子字符串从指定的 start 处开始,一直到索引 end - 1 处的字符,如果不存在这种字符,则一直到序列尾部。先将子字符串中的字符移除,然后将指定的 String 插入 start。(如果需要,序列将延长以适应指定的字符串。)

  参数:(包左不包右)
    start - 起始索引(包含)。
    end - 结束索引(不包含)。
    str - 将替换原有内容的字符串。
测试代码:

 public class StringBufferDemo_04 {
public static void main(String[] args) {
StringBuffer sb=new StringBuffer("我爱学习");
sb.replace(2,4,"睡觉");
System.out.println(sb);//我爱睡觉
//这里序列扩容了
sb.replace(2,9,"学习java");//我爱学习java
System.out.println(sb);
}
}


反转功能:

StringBuffer reverse()
  概述:将此字符序列用其反转形式取代。

代码测试:

 public class StringBuffer_05 {
public static void main(String[] args) {
StringBuffer sb1=new StringBuffer("Hello World!!");
sb1.reverse();
System.out.println(sb1);//!!dlroW olleH
}
}


截取功能:
 String substring(int start)
    返回一个新的 String,它包含此字符序列当前所包含的字符子序列。该子字符串始于指定索引处的字符,一直到此字符串末尾。

  参数:
    start - 起始索引(包含)。   
  返回:(注意:上面个所写的方法修改的都是本身,而subString返回的是一个String类型的字符串)
    新的字符串。

 String substring(int start, int end) 
    返回一个新的 String,它包含此序列当前所包含的字符子序列。 
    返回一个新的 String,它包含此序列当前所包含的字符子序列。该子字符串从指定的 start 处开始,一直到索引 end - 1 处的字符。

  参数(包左不包右):
    start - 起始索引(包含)。
    end - 结束索引(不包含)。 
  返回:
    新的字符串。

测试代码:

 public class StringBufferDemo_06 {
public static void main(String[] args) {
StringBuffer sb=new StringBuffer("hello world");
String s1=sb.substring(6);
System.out.println(s1);//wolrd
String s2=sb.substring(0,6);
System.out.println(s2);//hello
}
}

总结String 和StringBuffer互换问题:

String -- >StringBuffer:

a:通过构造方法

b:通过append()方法

 StringBuffer --> String:

a:通过构造方法

b:通过toString()方法

c:通过subString(0,length);



StringBuilder:
一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。
(单线程的环境下或者不会出现线程安全问题的多线程程序中应该使用StringBuilder)

多线程环境下只有只有在需要信息同步的时候才需要考虑线程安全:
同步(synchronized): 线程安全,效率低(你走我不走,我走你不走)
异步: 线程不安全,效率高(你走你的,我走我的)

构造方法:
和StingBuffer一样

区别:
String:不可变的字符序列
StringBuffer:可变的字符序列,线程安全,效率低
StringBuilder:可变的字符程序类,线程不安全,效率高,使用的多

StringBuffer和数组的区别:
StingBuffer:可扩容,可以添加任意数据,都会转换成对应 的文本表现形式
数组:长度固定,只能添加同一数据类型

关于StringBuffer的面试题:

String作为参数传递
StringBuffer作为参数传递

 public class StringBufferDemo6 {
public static void main(String[] args) {
String s1 = "Hello";
String s2 = "world";
change(s1, s2);
System.out.println("s1 = " + s1); // Hello
System.out.println("s2 = " + s2); // world StringBuffer sb1 = new StringBuffer("Hello");
StringBuffer sb2 = new StringBuffer("world");
change(sb1, sb2);
System.out.println("sb1 = " + sb1); // Hello
System.out.println("sb2 = " + sb2); // worldworld
} public static void change(StringBuffer sb1, StringBuffer sb2) {
sb1 = sb2;
sb2 = sb2.append(sb1);
} public static void change(String s1, String s2) {
s1 = s2;
s2 += s1;
}
}

 画图理解:




Java常用类StringBuffer详解的更多相关文章

  1. Java常用类object详解

    1.Object概述: 类Object是类层次结构的根类.每个类都使用Object作为超类.所有对象(包括数组)都实现这个类的方法. 2.构造方法详细信息: Object只有一个无参构造方法,因为ob ...

  2. java常用类-StringBuffer,Integer,Character

    * StringBuffer: * 线程安全的可变字符串. * * StringBuffer和String的区别? * 前者长度和内容可变,后者不可变. * 如果使用前者做字符串的拼接,不会浪费太多的 ...

  3. Java 常用类——StringBuffer&StringBuilder【可变字符序列】

    一.字符串拼接问题 由于 String 类的对象内容不可改变,所以每当进行字符串拼接时,总是会在内存中创建一个新的对象. Demo: 1 public class StringDemo { 2 pub ...

  4. Java 嵌套类基础详解

    目录 1. 什么是嵌套类? 2. 为什么要使用嵌套类? 3. 嵌套类的类型 4. 静态嵌套类 5. 非静态嵌套类 5.1 成员内部类 5.2 局部内部类 5.3 匿名内部类 6. 嵌套接口 1. 什么 ...

  5. java Object类源代码详解 及native (转自 http://blog.csdn.net/sjw890821sjw/article/details/8058843)

    package java.lang; public class Object { /* 一个本地方法,具体是用C(C++)在DLL中实现的,然后通过JNI调用.*/ private static na ...

  6. Java的类的详解

    首先呢,我承认上一次我理解的有误. 1.构造方法的作用:是初始化一个对象,而不是成员变量,它和get和set方法都有给成员变量赋值的功能. 2.下来说一下JVM调用main方法的过程: a.静态变量赋 ...

  7. 11-02 Java Object类使用详解

     Object 作为超类 Object是类层次结构的根类,所有的类都直接或者间接的继承自Object类. Object类的构造方法有一个,并且是无参构造,这其实就是理解当时我们说过,子类构造方法默认访 ...

  8. Java工具类DateFormatUtils详解

    日期和时间格式化实用程序和常量public static String format(Calendar calendar, String pattern) 说明:将日历格式化为特定的模式:参数:cal ...

  9. Properties类使用详解

    Java Properties类使用详解   概述 Properties 继承于 Hashtable.表示一个持久的属性集,属性列表以key-value的形式存在,key和value都是字符串. Pr ...

随机推荐

  1. 基于Anaconda编译caffe+pycaffe+matcaffe in Ubuntu[不用sudo权限]

    目录 caffe 编译 环境 github下载caffe源码 依赖 修改源码的编译配置 报错 测试使用 pycaffe caffe matcaffe caffe 编译 环境 Ubuntu16.04 C ...

  2. 201871010117-石欣钰《面向对象程序设计(java)》第十五周学习总结

    项目 内容 这个作业属于哪个课程 <任课教师博客主页链接>https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 <作业链接地址>http ...

  3. flask中的Flask、request、render_temple、redirect和url_for

    学flask也有一个多星期了,对这个web框架也有了一点的了解,梳理一些基础的知识点,还是小白一只,代码写得比较low,若文章有错误的地方欢迎大佬随时指正,代码中被注释掉的代码是关于预防csrf,无视 ...

  4. 洛谷 P1182 数列分段 Section II

    洛谷 P1182 数列分段 Section II 洛谷传送门 题目描述 对于给定的一个长度为N的正整数数列A-iA−i,现要将其分成M(M≤N)M(M≤N)段,并要求每段连续,且每段和的最大值最小. ...

  5. CloudCompare打开pcd文件

    Ubuntu下CloudCompare稳定版本无法打开pcd点云文件,切换到edge版本即可 $ sudo snap refresh --edge cloudcompare

  6. Codeforces Round #609 (Div. 2) 题解

    Equation Modulo Equality Long Beautiful Integer Domino for Young K Integers Equation \[ Time Limit: ...

  7. okhttp 发送get post 请求

    package com.qlwb.business.util; import java.util.Map; import com.alibaba.fastjson.JSON; import okhtt ...

  8. 【报名中】【5G探索】深度揭秘5G核心技术与挑战,云+社区开发者大会北京站等你来!

    报名渠道(扫描下方二维码) 开发者专属福利 限量手办 现场幸运签到开发者即可获得,早到获奖几率更大 幸运抽奖 一等奖:1名 JBL LIVE650 BTNC无线主动降噪智能耳机 二等奖:3名 JBL ...

  9. .NET Core:Json和XML

    (1)Json WebAPI默认使用Json格式,如果需要更改默认的Json设置在Startup的ConfigureServices方法中修改:services.AddMvc() .AddJsonOp ...

  10. maven集成命令-U -B -P -e -X

    maven -U clean compile install -e -X -Dmaven.test.skip=true 在持续集成服务器上使用怎样的 mvn 命令集成项目,这个问题乍一看答案很显然,不 ...