由于StringBuffer和StringBuilder的方法基本一样,我们以StringBuffer为例:
StringBuffer:线程安全的可变字符序列
线程(后面多线程中讲)
线程安全 --->同步的---->执行效率低举例:
银行的网站,医疗平台...
线程不安全---->不同步---->执行效率高
举例:
新闻网站,XXX论坛...
面试题:
StringBuffer和String的区别?
前者是一个可变的字符序列,后者是不可变的字符序列
如果从内存角度考虑,String定义的时候,会在常量池中开辟空间,比较耗费内存
而StringBuffer,字符串缓冲区(里面存储的全部都是字符串),它会释放掉
下来我们通过API文档来学习StringBuffer:
StringBuffer的构造方法
StringBuffer() :无参构造的形式,初始容量16StringBuffer(int capacity) :指定容量构造一个字符串缓冲区
StringBuffer(String str) 构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容
StringBuffer的获取功能
public int length()返回长度public int capacity()返回当前容量 (如果超过容量,系统自动分配(存储字符串的时候,英文的))
public class StringBufferDemo {
public static void main(String[] args) {
// StringBuffer() :无参构造的形式,初始容量16
//创建一个字符串缓冲区
StringBuffer sb = new StringBuffer() ; //实际开发中,默认无参构造
System.out.println("sb:"+sb);//:当前缓冲区没有字符序列...
System.out.println("length():"+sb.length());
System.out.println("capacity():"+sb.capacity());
System.out.println("------------------------");
//StringBuffer(int capacity) :指定容量构造一个字符串缓冲区
StringBuffer sb2 = new StringBuffer(50) ;
System.out.println("length():"+sb2.length());
System.out.println("capacity():"+sb2.capacity());
System.out.println("------------------------");
//StringBuffer(String str) 构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容
StringBuffer sb3 = new StringBuffer("hello");
System.out.println("sb3:"+sb3);
System.out.println("length():"+sb3.length());
System.out.println("capacity():"+sb3.capacity());//初始容量+当前字符数
//StringBuffer sb4 = "hello" ; 不能直接转换(类型不匹配,不能直接将一个字符串类赋值给一个对象类型 StringBuffer)
}
}
StringBuffer的添加功能
public StringBuffer append(String/boolean....):在字符串缓冲区中追加数据(在末尾追加),并且返回字符串缓冲区本身(实际开发中用的多)public StringBuffer insert(int offset,String str):将当前str字符串添加到指定位置处,它返回字符串缓冲区本身
StringBuffer的删除功能
public StringBuffer deleteCharAt(int index):移除指定位置处的字符..public StringBuffer delete(int start,int end):移除从指定位置处到end-1处的子字符串...
StringBuffer的反转功能
public StringBuffer reverse() :将缓冲区中的字符序列反转取代,返回它(字符串冲)本身
StringBuffer的截取功能
public String substring(int start):从指定位置开始截取,默认截取到末尾,返回值不在是缓冲区本身,而是一个新的字符串public String substring(int start,int end):从指定位置开始到指定位置结束截取,包前不包后,返回值不在是缓冲区本身,而是一个新的字符串
StringBuffer的替换功能
public StringBuffer replace(int start,int end,String str):从指定位置到指定位置结束,用新的str字符串去替换,返回值是字符串缓冲区本身
下来举个例子体会一下:
public class StringBufferDemo2 {
public static void main(String[] args) {
//创建一个字符串缓冲区对象
StringBuffer sb = new StringBuffer() ;
//直接追加功能
sb.append("hello") ;
sb.append("world") ;
System.out.println("sb:"+sb);
//insert
sb.insert(5, "JavaSE");
System.out.println("sb:"+sb);
//delete
//需求:移除JavaSE
sb.delete(5, 11);
System.out.println("sb:"+sb);
//反转
sb.reverse() ;
System.out.println("sb:"+sb);
sb.reverse();
//子字符串
String str = sb.substring(5) ;
System.out.println("str:"+str);
String str2 = sb.substring(5, 10) ;
System.out.println("str2:"+str2);//返回的是被截取的字符串
//replace
sb.replace(5, 10,"生日快乐") ;
System.out.println("sb:"+sb);
}
}
运行结果:
sb:helloworld
sb:helloJavaSEworld
sb:helloworld
sb:dlrowolleh
str:world
str2:world
sb:hello生日快乐
下来我们学习一下String和StringBuffer之间的相互转换。那么你可能要问为什么需要类与类之间的相互转换呢?我们将A类型转换成B类型,是为了使用B类的功能,有时候又需要将B类转换成A类,因为这时需要的是A类型。下面这个代码就完成了String和StringBuffer的相互转换。
public class StringBufferTest {
public static void main(String[] args) {
//String--->StringBuffer
String s = "hello";
//方式1 :带参构造,StringBuffer(String str)
StringBuffer sb = new StringBuffer(s) ;
//方式2:可以通过无参构造创建字符串缓冲区对象,给缓冲区中追加内容
StringBuffer sb2 = new StringBuffer() ;
sb2.append(s) ;
System.out.println("sb:"+sb);
System.out.println("sb2:"+sb2);
System.out.println("----------------------------");
//StringBuffer--->String
StringBuffer buffer = new StringBuffer("world") ;
//方式1:public String(StringBuffer buffer)分配一个新的字符串,它包含字符串缓冲区参数中当前包含的字符序列
String str = new String(buffer) ;
//方式2:StringBuffer的功能:public String toString()返回此序列中数据的字符串表示形式
String str2 = buffer.toString() ;
System.out.println("str:"+str);
System.out.println("str2:"+str2);
}
}
我们在讲String类的时候写过一个将字符数组拼接成字符串的例子,在StringBuffer里有一个更简单的方法,toString(),该方法返回此序列数据的字符串表示形式,下面我们就用toString方法重新写一下这个例子:
public class StringBufferTest2 {
public static void main(String[] args) {
//定义一个数组
int[] arr = {1, 2, 3} ;
//StringBuffer进行实现
String str = arrayToString2(arr) ;
System.out.println("str:"+str);
}
public static String arrayToString2(int[] arr) {
//创建字符串缓冲区对象
StringBuffer sb = new StringBuffer() ;
//追加左中括号
sb.append("[") ;
//遍历数组
for(int x = 0 ;x < arr.length ; x ++) {
//判断
if(x==arr.length-1) {
sb.append(arr[x]);
}else {
sb.append(arr[x]).append(", ") ;
}
}
sb.append("]") ;
return sb.toString() ;
}
}
我们再来练习一个例子:
键盘录入一个字符串,判断该字符串是否是对称字符串
例如"abc"不是对称字符串,"aba"、"abba"、"aaa"、"mnanm"是对称字符串
分析:
用键盘录入改进
字符串中的第一个字符和最后一个字符比较
用第二个和倒数第二个...
......
比较的长度length/2
但在StringBuffer里有一个更为简单的方法,还记得reverse方法吗?只要判断reverse之后的字符串跟原来是否相同,相同则为对称字符串,否则不对称。
public class StringBufferTest3 {
public static void main(String[] args) {
//创建键盘录入对象:
Scanner sc = new Scanner(System.in) ;
//接收数据
System.out.println("请输入一个字符串:");
String line = sc.nextLine() ;
//用方法改进
boolean flag = isSame(line) ;
System.out.println("flag:"+flag);
}
//StringBuffer
public static boolean isSame(String s) {
//创建字符串缓冲区对象
/*StringBuffer sb = new StringBuffer(s) ;
//反转
String str = sb.reverse().toString() ;
return str.equals(s) ;*/
//一步走
return new StringBuffer(s).reverse().toString().equals(s);
}
}
学习了StringBuffer,我们来看两个面试题:
1、StringBuffer,String,StringBuilder的区别?
StringBuffer和StringBuilder都是一个可变的字符序列,提供一个缓冲区.(两者都看做容器)
StringBuffer:线程安全的,同步的,执行效率低
StringBuilder:线程不安全的,不同步的,执行效率高,并且单线程中优先采用StringBuilder
StringBuffer 执行效率虽然低,但是优于String类型,并且他是可变的字符序列,且提供了缓冲区
2、StringBuffer和数组的区别?
数组:它是可以存储多个数据的容器,并且多个数据的类型必须一致
数组长度功能:length属性
StringBuffer:它是容器,它在缓冲区始终存储的只能字符串类型的数据
获取缓冲区的长度:length()