目录
13、探究String作为参数传递与StringBuffer作为参数传递的区别
1、把数组拼接成一个字符串(用StringBuffer实现)
一、StringBuffer类
1、概述:
线程安全的可变字符序列
2、线程安全与不安全:
不安全就是指存在同步操作同一数据的行为,效率高
实际开发过程中,效率和安全问题很难平衡
3、StringBuffer的特点:
(1)、线程安全,没有同步操作,效率低
(2)、StringBuffer是一个可变序列
(3)、StringBuffer又称之为字符串缓冲区,把它当作一个字符串去操作,只不过它与String相比是 可以修改内容的
4、可修改
在任何时间点,它包含着一些特定的字符序列,但是可以通过某些方法修改这些字符序列的长度和内容
5、StringBffer与String的区别:
(1)、StringBuffer的长度和内容都可以发生改变,String不可以
(2)、String每创建一个新的字符串都会开辟一个新的常量池区域;StringBuffer会提前给出容量, 可以进行字符串的拼接,而不会重新开辟空间。
6、StringBuffer的构造方法:
public StingBuffer():构造一个没有字符的字符串缓冲区,初始容量为16个字符
public StringBuffer(int capacity):构造一个没有字符的字符串缓冲区和指定的初始容量
public StringBuffer(String str):构造一个初始化内容为指定字符串内容的字符串缓冲区
这里引出:
public int capacity():返回当前容量。
public int length():返回长度(字符数)。
举例说明:
public class StringBufferDemo1 {
public static void main(String[] args) {
//public StringBuffer() 构造一个没有字符的字符串缓冲区,初始容量为16个字符。
StringBuffer sb1 = new StringBuffer();
System.out.println("sb1:" + sb1); //StringBuffer重写了toString方法
//如何获取StringBuffer的容量
//public int capacity()返回当前容量。
System.out.println("当前StringBuffer的容量为:" + sb1.capacity());
//public int length()返回长度(字符数)。
System.out.println("StringBuffer中字符串的长度为:" + sb1.length());
System.out.println("===================================================");
//public StringBuffer(int capacity) 构造一个没有字符的字符串缓冲区和指定的初始容量。
StringBuffer sb2 = new StringBuffer(50);
System.out.println("sb2:" + sb2); //StringBuffer重写了toString方法
//如何获取StringBuffer的容量
//public int capacity()返回当前容量。
System.out.println("当前StringBuffer的容量为:" + sb2.capacity());
//public int length()返回长度(字符数)。
System.out.println("StringBuffer中字符串的长度为:" + sb2.length());
System.out.println("===================================================");
//public StringBuffer(String str) 构造一个初始化为指定字符串内容的字符串缓冲区。
StringBuffer sb3 = new StringBuffer("hello");
System.out.println("sb3:" + sb3); //StringBuffer重写了toString方法
//如何获取StringBuffer的容量
//public int capacity()返回当前容量。
System.out.println("当前StringBuffer的容量为:" + sb3.capacity()); // 21 = 16 + 5
//public int length()返回长度(字符数)。
System.out.println("StringBuffer中字符串的长度为:" + sb3.length()); // 5
}
}
运算结果:
7、StringBuffer的添加功能:
public StringBuffer append(String str):
通过观察API发现:不光可以追加字符串,还可以是任意数据类型的追加到StringBuffer中
返回的StringBuffer是字符串缓冲区本身
无论什么类型,追加到StringBuffer中全部变成了字符串
public StringBuffer insert(int index,String str):
将字符串str插入到此字符序列中,返回字符串缓冲区本身,按顺序插入到指定index的该序列中,向上移动原来位于该位置的任何字符,并将该序列的长度加到参数的长度。
举例说明:
public class Test2 {
public static void main(String[] args) {
StringBuffer s1=new StringBuffer();
StringBuffer s2 = s1.append("hello");
System.out.println(s1);//hello
System.out.println(s2);//hello
System.out.println(s1==s2);//true
// s1与s2比较结果为true进一步说明返回的是StringBuffer本身
s2.append(10);
s2.append('a');
s2.append(true);
s2.append(13.24);
System.out.println(s2);
// 无论什么类型都变成了字符串
// 这里结果为:hello10atrue13.24
// 链式编程追加
s2.append(10).append('a').append(true).append(13.24);
System.out.println(s2);
// 结果:hello10atrue13.2410atrue13.24
System.out.println("================================");
// 插入操作:
s2.insert(5,"HADOOP");
System.out.println(s2);
// 结果:helloHADOOP10atrue13.2410atrue13.24
// 如果插入的是null,四个字符'null'也会被插入到该序列中,但是不可以直接插入:
// s2.insert(5,null);
Object o=null;
s2.insert(5,o);
System.out.println(s2);
// 结果:hellonullHADOOP10atrue13.2410atrue13.24
}
}
运算结果:
8、StringBuffer的删除功能:
public StringBuffer deleteCharAt(int index):
删除指定索引处的字符,该序列缩短了一个char
注意:如果index为负数或者大于等于length(),运行时会报错。
index的值最大可以取到实际存储字符串的长度-1。
public StringBuffer delete(int start,int end):
删除此序列的子字符串中的字符,子字符串开始于指定start索引处并延伸到字符索引end-1,或者没有这样的子字符串序列存在,则结束。
注意:如果start等于end,则不做任何修改,且删除位置索引为:start<=index<end,索引end处的字符不会被删除,但是start处的字符会被删除。故start索引位置一定要是已经存在的索引,否则会报错。
举例说明:
public class StringBufferDemo3 {
public static void main(String[] args) {
//使用带参数的构造方法创建StringBuffer对象
StringBuffer sb = new StringBuffer("bigdata");
System.out.println("未做删除操作之前的StringBuffer:" + sb);
// StringBuffer sb2 = sb.deleteCharAt(3); // 操作的是同一个StringBuffer对象
// System.out.println(sb);
// System.out.println(sb2);
// System.out.println(sb==sb2);
sb.deleteCharAt(3);
System.out.println("做删除操作之后的StringBuffer:" + sb);
//如果 index为负数或大于或等于length() 。
//index的值最大可以取到实际存储字符串的长度-1
// sb.deleteCharAt(30);
// sb.deleteCharAt(6);
System.out.println("===============================================");
//public StringBuffer delete(int start,int end)
//删除此序列的子字符串中的字符。
// 子串开始于指定start并延伸到字符索引end - 1 ,或如果没有这样的字符存在的序列的结束。
// 如果start等于end ,则不作任何更改。
// start<=index<end
//bigata
// sb.delete(2,5);
// sb.delete(2,6);
// sb.delete(2,10);
//注意开始位置一定是已经存在的索引,否则报错
// sb.delete(8,10);
System.out.println(sb);
//需求:删除StringBuffer中的所有字符
sb.delete(0, sb.length());
System.out.println("删除StringBuffer中的所有字符:" + sb);
}
}
运算结果;
9、StringBuffer中的替换功能:
public StringBuffer replace(int start,int end,String str):
用指定Str中的字符替换此序列的子字符串中的String,子字符串开始于指定索引start处并延伸到字符索引end-1处,或者没有这样的子字符串的存在,则结束
第一子字符串的字符被删除,然后指定str被插入在start位置
举例说明:
public class StringBufferDemo4 {
public static void main(String[] args) {
//创建一个StringBuffer对象
StringBuffer sb = new StringBuffer();
//往StringBuffer中添加一些内容
sb.append("java").append("mysql").append("hadoop").append("hive").append("spark").append("flink");
System.out.println(sb);
//public StringBuffer replace(int start,int end,String str)
sb.replace(5,9,"阿杰真帅");
System.out.println(sb);
}
}
运算结果:
10、StringBuffer的反转功能:
public StringBuffer reverse():
导致该字符序列被序列的相反代替,如果序列中包含任何替代对,则将它们视为单个字符进行反向操作
举例说明:
public class StringBufferDemo5 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append("我爱你中国");
System.out.println("反转之前:" + sb);
System.out.println("反转之后:");
StringBuffer sb2 = sb.reverse(); // 操作的是同一个StringBuffer对象
System.out.println(sb);
System.out.println(sb2);
}
}
运算结果:
11、StringBuffer的截取功能:
public String substring(int start):
返回一个新的String,其中包含此字符序列当前包含的字符的子序列。
public String substring(int start,int end):
返回一个新的String,其中包含此序列中当前包含的字符的子序列。子字符串开始于指定的start索引,并扩展到索引end-1处。
两种截取不会影响原来的StringBuffer的数据,且返回值为String类型
举例说明:
public class StringBufferDemo6 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append("java")
.append("mysql")
.append("hive")
.append("ETL")
.append("spark");
System.out.println(sb);
//public String substring(int start)
//不会改变原来StringBuffer中的数据
//返回值是一个String类型的数据
String s1 = sb.substring(4);
System.out.println("截取的内容是:"+s1);
System.out.println("StringBuffer的内容为:"+sb);
//public String substring(int start,int end) 含头不含尾 [start,end)
//javamysqlhiveETLspark
String s2 = sb.substring(9, 13);
System.out.println("截取的内容是:"+s2);
System.out.println("StringBuffer的内容为:"+sb);
}
}
运算结果:
12、String与StringBuffer之间的转换。
为什么要进行相互转换?
A-->B,将A转换成B,是为了使用B中的特有功能
B-->A,再将B转换成A,可能是引用最终的结果需要的是A类型的数据,所以还得转换回来
代码实现:
public class StringBufferDemo7 {
public static void main(String[] args) {
//String --> StringBuffer
String s = "hello";
// StringBuffer sb = s;
//java: 不兼容的类型: java.lang.String无法转换为java.lang.StringBuffer
// StringBuffer sb = "hello";
//方式1:通过构造方法转换
StringBuffer sb1 = new StringBuffer(s);
System.out.println(s);
System.out.println(sb1);
//方式2:通过append()
StringBuffer sb2 = new StringBuffer();
sb2.append(s);
System.out.println(s);
System.out.println(sb2);
System.out.println("==============================================");
//StringBuffer --> String
StringBuffer sb3 = new StringBuffer("bigdata");
//方式1:toString()方法
String s1 = sb3.toString();
System.out.println(sb3);
System.out.println(s1);
//方式2:subString
String s2 = sb3.substring(0);
System.out.println(s2);
System.out.println(sb3);
//方式3:String类的构造方法
//String(StringBuffer buffer)
//分配一个新的字符串,其中包含当前包含在字符串缓冲区参数中的字符序列。
String s3 = new String(sb3);
System.out.println(s3);
System.out.println(sb3);
}
}
运算结果:
13、探究String作为参数传递与StringBuffer作为参数传递的区别
面试题1:String,StringBuffer,StringBuilder之间的区别
1、StringBuffer是线程同步安全的,数据安全,效率低。
StringBuilder不是线程同步安全的,数据不安全,效率高。
2、String的内容是不可改变的,StringBuffer和StringBuilder是可变序列。
3、StringBuffer中方法上有synchronized关键字。面试题2:StringBuffer和数组的区别?
它们都可以被看作是一个容器,装一些数据。
但是,StringBuffer里面的数据都是一个一个字符
数组可以存放不同数据类型的数据,但是同一个数组只能存放同一种数据类型的数据。
代码:
public class StringBufferDemo8 {
public static void main(String[] args) {
// //创建一个StringBuffer的对象
// StringBuffer stringBuffer = new StringBuffer();
// //创建一个StringBuilder的对象
// StringBuilder stringBuilder = new StringBuilder();
String s1 = "hello";
String s2 = "world";
System.out.println("s1: " + s1 + ",s2: " + s2);
change(s1, s2);
System.out.println("s1: " + s1 + ",s2: " + s2);
System.out.println("========================================");
StringBuffer sb1 = new StringBuffer("hello");
StringBuffer sb2 = new StringBuffer("world");
System.out.println("sb1: " + sb1 + ",sb2: " + sb2); // hello world
change(sb1, sb2);
System.out.println("sb1: " + sb1 + ",sb2: " + sb2); // sb1: hello,sb2: worldworld
//当多个StringBuffer作为参数传参的时候,谁发生了操作,谁就会受到影响‘
}
public static void change(StringBuffer sb1, StringBuffer sb2) {
sb1 = sb2;
sb2.append(sb1);
System.out.println("sb1: " + sb1 + ",sb2: " + sb2);
//sb1: worldworld,sb2: worldworld
}
public static void change(String s1, String s2) {
s1 = s2;
s2 = s1 + s2;
System.out.println("s1: " + s1 + ",s2: " + s2);
}
}
运算结果:
二、StringBuffer类练习题
1、把数组拼接成一个字符串(用StringBuffer实现)
public class StringBufferTest1 {
public static void main(String[] args) {
char[] chars = {'a','b','c','d'};
//创建一个空的StringBuffer对象
StringBuffer sb = new StringBuffer();
//遍历数组得到每一个字符
for(int i=0;i<chars.length;i++){
sb.append(chars[i]);
}
//将字符缓冲区转换一个字符串
String s = sb.toString();
System.out.println(s);
}
}
2、把字符串反转 (键盘录入字符串)
import java.util.Scanner;
public class StringBufferTest2 {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
System.out.println("请输入字符串:");
String stringLine = sc.next();
//方式1:使用String的拼接方式
String s = "";
//将字符串转换成字符数组
char[] chars = stringLine.toCharArray();
//倒着遍历字符数组
for (int i = chars.length - 1; i >= 0; i--) {
s += chars[i];
}
System.out.println(stringLine + "反转之后的结果为:" + s);
System.out.println("========================================");
//方式2:StringBuffer中有一个reverse()方法实现
//将输入的String类型的数据转换成StringBuffer类型
StringBuffer sb = new StringBuffer(stringLine);
sb.reverse();
//将StringBuffer类型转换回去String类型
String s1 = sb.toString();
System.out.println(stringLine + "反转之后的结果为:" + s1);
System.out.println("=====================链式编程改进:=====================");
System.out.println(new StringBuffer(stringLine).reverse().toString());
}
}
3、判断一个字符串是否是对称字符串
import java.util.Scanner;
public class StringBufferTest3 {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
System.out.println("请输入要判断的字符串:");
String stringLine = sc.next();
//方式1:一个一个的去比较
//将输入的字符串转化成字符数组
boolean flag = true;
char[] chars = stringLine.toCharArray();
for (int start = 0, end = chars.length - 1; start <= end; start++, end--) {
if (chars[start] != chars[end]) {
System.out.println("该字符串不是对称字符串");
flag = false;
break;
}
}
if(flag){
System.out.println("该字符串是对称字符串");
}
System.out.println("=========================================================");
//方式2:利用StringBuffer中反转方法,如果反转之前与反转之后的字符串是一样的,说明是对称字符串
//将输入的String类型的数据转化成StringBuffer类型的数据
StringBuffer sb = new StringBuffer(stringLine);
sb.reverse();
//再将反转后的StringBuffer类型的数据转换成String类型的数据
String s = sb.toString();
if(s!=null){
if(s.equals(stringLine)){
System.out.println("该字符串是对称字符串");
}else {
System.out.println("该字符串不是对称字符串");
}
}
}
}