String
- 由于,每次拼接操作,都会构建一个新的String对象,所以String既耗时又浪费空间
StringBuffer
- 线程安全的,同步的
- String的字符串的缓冲区,可变字符序列(长度内容可变)
StringBuilder (用的最多,单线程中)
- 线程不安全的,不保证同步
- 作为StringBuffer的简易替换,用在字符串缓冲区被单个线程使用的时候
- 构造和方法:与StringBuffer一模一样
Question:
1.三者的区别
(1)String是内容不可变的,而StringBuffer,StringBuilder都是内容可变的
(2)StringBuffer是同步的,数据安全,效率低,StringBuilder是不同步的,数据不安全,效率高
2.StringBuffer和数组的区别
(1)二者都可以看出是一个容器,装其他的数据
(2)StringBuffer的数据最终是一个字符串数据
(3)数组可以放置多种数据,但必须是同一种数据类型
3.形式参数问题
- 基本类型: 形式参数的改变不影响实际参数(String字符串是常量值,可以把他看成特殊的基本类型来看)
- 引用类型: 形式参数如果是对象或者数组的话,其改变直接影响实际参数(StringBuffer是引用类型,底层是数组,直接赋值main函数里面对象值依然不变,操作类如以下的append方法会变)
public class StringBufferTest {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "world";
System.out.println(s1 + "---" + s2);// hello---world
change(s1, s2);
System.out.println(s1 + "---" + s2);// hello---world
StringBuffer sb1 = new StringBuffer("hello");
StringBuffer sb2 = new StringBuffer("world");
System.out.println(sb1 + "---" + sb2);// hello---world
change(sb1, sb2);
System.out.println(sb1 + "---" + sb2);// hello---worldworld
}
private static void change(String s1, String s2) {
s1 = s2;
s2 = s1 + s2;
}
private static void change(StringBuffer sb1, StringBuffer sb2) {
sb1 = sb2;
sb2.append(sb1);
}
}
下面列举一些String里面没有的方法,即对字符串缓冲区进行增删改的操作
添加功能
append:可以把任意类型数据添加到字符串缓冲区里面,并返回字符串缓冲区本身
(StringBuffer的append返回的是其本身,而String没有append方法,原因是它是不可变的)
StringBuffer sb = new StringBuffer();
sb.append("hello").append("true");
insert(int offset,String str):指定位置把任意类型的数据插入到字符串缓冲区里面,返回字符串缓冲区本身(接上面的代码)
sb.insert(5,"world");
删除功能
deleteCharAt(int index):删除指定位置的字符,并返回本身
delete(int start,int end):删除从指定位置开始指定位置结束的内容,并返回本身(接上面的代码)
sb.deleteCharAt(1);//删除下标为1的位置的元素
sb.delete(5,10);//基本都是包左不包右
sb.delete(0,sb.length());//删除所有的数据
替换功能
replace(int start,int end,String str):从start开始到end用str替换,包左不包右,返回本身
注:String里面也有替换功能,但生成一个新的常量放在方法区的静态区中,然后用另一个对象去指向它,自身不发生改变
sb.replace(5,10,"生日快乐");//
反转功能
reverse():将自身反转,返回自身 如:abc -> cba
sb.reverse();
截取功能
注:以下返回的是String对象,这个方法和String一样,返回的是新的一个String对象,而非本身
subString(int start)
subString(int start,int end)
sb.subString(5);//从下标5开始截取到最后,返回一个值
sb.subString(5,10);
以下介绍下String和StringBuffer的相互转换
StringBuffer sb = "hello" //错误,不能直接把字符串的值赋给StringBuffer
正确如下
//以下为String -- StringBuffer
//方式1:通过构造方法
String s = "hello";
StringBuffer sb = new StringBuffer(s);
//方法2:通过append()方法
StringBuffer sb2 = new StringBuffer();
sb2.append(s);
//以下为StringBuffer -- String
StringBuffer buffer = new StringBuffer("java");
//方式1:通过构造方法
String str = new String(buffer);
//方式2:通过toString()方法
String str2 = buffer.toString();
下面介绍拼接字符串的方法,从中可以看出String和StringBuffer的区别
//功能:将一个数组拼接成一个字符串
public class StringBufferTest {
public static void main(String[] args) {
// 定义一个数组
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// 方式一:通过String来拼接,每一步拼接都会产生一个新串,效率低
String result = arrayToString(arr);
System.out.println(result);
// 方式二:通过StringBuffer拼接,对本身进行修改
String result2 = arrayToString2(arr);
System.out.println(result2);
}
// String
public static String arrayToString(int[] arr) {
String s = "";
s += "[";
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
s += arr[i];
} else {
s += arr[i];
s += ",";
}
}
s += "]";
return s;
}
// StringBuffer
public static String arrayToString2(int[] arr) {
StringBuffer sb = new StringBuffer();
sb.append("[");
for (int i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
sb.append(arr[i]);
} else {
sb.append(arr[i]).append(",");
}
}
sb.append("]");
return sb.toString();
}
}
下面介绍反转功能的String和StringBuffer的功能实现
import java.util.Scanner;
//把字符串反转
public class StringBufferTest {
public static void main(String[] args) {
// 键盘录入
Scanner sc = new Scanner(System.in);
System.out.println("请输入数据:");
String s = sc.nextLine();
// 方式一:通过String把字符串反转
String result = myReverse(s);
System.out.println(result);
// 方式二:用StringBuffer的方法
String result2 = myReverse2(s);
System.out.println(result2);
}
public static String myReverse(String s) {
char[] charArray = s.toCharArray();
String str = "";
for (int i = charArray.length - 1; i >= 0; i--) {
str += charArray[i];
}
return str;
}
public static String myReverse2(String s) {
StringBuffer sb = new StringBuffer(s);
sb.reverse();
return sb.toString();
}
}
下面介绍判断字符串是否对称的方法,可以看出StringBuffer比String简便很多
import java.util.Scanner;
//判断一个字符串是否对称
public class StringBufferTest {
// 第一个和最后一个比较,第二个和倒数第二个比较,比较的次数为长度/2
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串:");
String s = sc.nextLine();
// 一个个的比较
System.out.println(isSame(s));
// 用StringBuffer的反转功能
System.out.println(isSame2(s));
}
public static boolean isSame(String s) {
boolean flag = true;
char[] charArray = s.toCharArray();
for (int start = 0, end = charArray.length - 1; start <= end; start++, end--) {
if (charArray[start] != charArray[end])
flag = false;
break;
}
return flag;
}
public static boolean isSame2(String s) {
return new StringBuffer(s).reverse().toString().equals(s);
}
}