StringBuffer类:
基本介绍:
java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删
很多方法与String相同,但StringBuffer是可变长度的。
StringBuffer是一个容器。
我们进行查看StringBuffer,如下所示:
package com.ypl.stringbuffer_; public class StringBuffer01 { public static void main(String[] args) { //1.StringBuffer的直接父类是AbstractStringBuilder //2.StringBuffer实现了Serializable(序列化接口),即StringBuffer的对象可以串行化. //3.在父类中 AbstractStringBuilder有属性char [] value,不是final类型的,从父类AbstractStringBuffer继承下来的char [] value,该value数组存放字符串内容,引出存放在堆中的,不再是存放在常量池了。 //4.因为StringBuffer字符内容是存在char[] value,所以在变化(增加(如果数据存储不下来,即进行双倍扩容,同时将数据拷贝过来,更改地址,即改变指向)或删除)时不用每次都更换地址(即不是每次都创建新的对象),所以效率高于String。 StringBuffer stringBuffer = new StringBuffer("hello"); } }
我们查看他的类图如下所示:
我们查看StringBuffer的·源码如下所示:
public final class StringBuffer
//StringBuffer是一个final类,不能被继承。
extends AbstractStringBuilder
implements Serializable, CharSequence
里面进去为声明性质的接口Serializable:
我们再进去他的父类:存放内容是在 char [ ] value.
String VS StringBuffer
(1)String保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更改地址,效率较低 //public final char value[ ];
(2)StringBuffer保存的是字符串变量,里面的值可以修改,每次StringBuffer的更新实际上可以更新内容,不用每次更新地址,效率较高 //char[ ] value ;//放在这个堆
StringBuffer的构造器:
(1)StringBuffer( ):构造一个其中的不带字符的字符串缓冲区,其初始容量为16个字符
我们追进去如下所示:
我们继续追进去如下所示:
(2)StringBuffer(CharSequence seq ) :构造一个字符串缓冲区,它包含与指定的CharSequence相同的字符
(3)StringBuffer(int capacity )://capacity容量,构造一个不带字符,但具有指定初始容量的字符串缓冲区,即对char[ ]大小进行指定
我们追进去如下所示:
(4)StringBuffer(String str ) :构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容
我们创建如下:
我们追进去如下所示:
String和StringBuffer之间的相互转换。
我们的代码如下所示:
package com.ypl.stringbuffer_;
public class StringAndStringBuffer {
public static void main(String[] args) {
//String--->StringBuffer
String str="hello tom";
//方式1 使用构造器
//注意:返回的才是StringBuffer对象,对Str本身没有影响
StringBuffer stringBuffer = new StringBuffer(str);
System.out.println(stringBuffer);
//方式2:使用的是append方法
StringBuffer append = new StringBuffer().append(str);
//StringBuffer---->String
StringBuffer stringBuffer3 = new StringBuffer("rgf");
//方式1:使用StringBuffer提供的toString方法
String s = stringBuffer3.toString();
//方式2:使用构造器来搞定
String s1 = new String(stringBuffer3);
}
}
StringBuffer类的常用方法:
(1)增:append
package com.ypl.stringbuffer_;
public class StringBufferMethod {
public static void main(String[] args) {
StringBuffer s = new StringBuffer("hello");
//增:append
s.append(',');//"hello,"
s.append("张三丰"); //"hello,张三丰"
s.append("赵敏").append(100).append(true).append(10.5); //"hello,张三丰赵敏100true10.5
/*
我们查看toString返回的方法
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
}
*/
System.out.println(s);
//
}
}
我们查看toString的源码进行解析:我们进行debug如下所示:
(2)删:delete(start,end)
(3)改 :replace(start,end,string) //将start----end间的内容替换掉,不含end
(4)查:indexOf //查找子串在字符串第一次出现的索引,如果找不到返回-1
(5)插:iinsert
(6)获取长度:length
我们通过代码来进行了解:
package com.ypl.stringbuffer_;
public class StringBufferMethod {
public static void main(String[] args) {
StringBuffer s = new StringBuffer("hello");
//增:append
s.append(',');//"hello,"
s.append("张三丰"); //"hello,张三丰"
s.append("赵敏").append(100).append(true).append(10.5); //"hello,张三丰赵敏100true10.5”
/*
我们查看toString返回的方法
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
}
*/
System.out.println(s);
/*
删:delete(start,end)
删除索引为>=start && <end 处的字符
删除11到14的字符(但不包括14)[11,14)
*/
s.delete(11,14);
System.out.println(s); //"hello,张三丰赵敏true10.5“
//改 :replace(start,end,string) //将start----end间的内容替换掉,不含end
//使用"周芷若"替换9-11的字符。
s.replace(9,11,"周芷若");
System.out.println(s); //"hello,张三丰周芷若true10.5
//查:indexOf //查找子串在字符串第一次出现的索引,如果找不到返回-1
int indexOf = s.indexOf("张三丰");
System.out.println(indexOf);
//插:insert
//在索引为9的位置,插入“赵敏”原来索引为9的内容自动后移
s.insert(9,"赵敏");
System.out.println(s);
//获取长度:length
System.out.println( s.length());//22
System.out.println(s);
}
}
我们运行之后如下所示:
StringBuffer测试题1如下所示:
我们的代码设置如下所示:
public class StringBufferExercise { public static void main(String[] args) { String str=null; StringBuffer sb = new StringBuffer(); sb.append(str);//需要看源码,底层调用的是父类的AbstractStringBuilder的appendNull方法 /** * 我们查找append方法: *我们进行打断点,我们追加进去之后如下所师: * public synchronized StringBuffer append(String str) { * toStringCache = null; * super.append(str); * return this; * } */ System.out.println(sb.length()); //4 System.out.println(sb); //null
我们进行debug查看如下所示:
![]()
我们上面了解到StringBuffer的父类如下所示:AbstractStringBuilder
我们查看他的父类的代码
我们发现如果str为null,我们返回appendNull,我们继续查看其源码:
![]()
我们发现是把我们的空对象转成字符数组'n' 'u' 'l' 'l'。
我们运行之后如下所示:
我们在上面的基础上增加如下代码:
String str=null; StringBuffer sb1 = new StringBuffer(str); //看底层源码 System.out.println(sb1);
我们继续追加代码:
我们发现是我们首先计算传进去的字符串的长度,我们传进去的为null,这个时候就会出现问题,我们会执行:super(null.length( ) +16);我们会直接抛出空指针异常。
我们运行之后发现出现如下所示:
的确抛出空指针异常。
StringBuffer测试题2如下所示:
输入商品名称和商品价格,要求打印效果如下所示,使用该方法完成:
商品名 商品价格
手机 123,657.59
要求:价格的小数点前面每三位用逗号隔开,再输出。
我们设计的代码如下所示:
package com.ypl.stringbuffer_; import java.util.Scanner; public class StringBufferMethod01_ { public static void main(String[] args) { /** * 输出如下格式: * 商品名 商品价格 * 手机 123,657.59 * 要求:价格的小数点前面每三位用逗号隔开,再输出。 */ /*思路分析: 1.定义一个Scanner对象,接收用户输入的价格(String) */ //2.希望使用到StringBuffer的insert方法,需要将String转成StringBuffer //3.然后使用相关方法进行字符串的处理 Scanner scanner = new Scanner(System.in); if (scanner.hasNext()) { //String str="125553555345.55"; String str = scanner.next(); StringBuffer stringBuffer = new StringBuffer(str); for (int i = stringBuffer.lastIndexOf(".") - 3; i > 0; i -= 3) { // int j= stringBuffer.lastIndexOf("."); stringBuffer = stringBuffer.insert(i, ","); } System.out.println(stringBuffer); //上面的两步需要做一个循环处理,才是正确的。 } scanner.close(); } }
我们运行之后如下所示: