可变字符串类其实就是描述一个字符串可以改变的类;前面学习了一个String类,所有可以双引号描述的内容我们都可以用String类加以描述,但是String类描述的内容是常量(值不可改变)
假设我想要描述123这时候是不是需要创建一块内存空间描述123,这时候如果我还想描述124是不是需要再创建一块内存空间描述124,如果还想描述125是不是需要再创建内存空间描述125?
123,124,125非常类似,但是在部分场合中123使用完一次以后就再也用不到了,124、125同理,每次都调用String类创建常量有点浪费时间浪费空间,接下来如果我直接把123改成124这样就剩下了,可以剩下大量的产生内存释放内存的操作;而需要解决上述的问标需要使用以下两个类:java.lang.StringBuilder类和java.lang.StringBuffer(直接在一块内存空间中把123改成124、125)
区别:
String类描述的字符串是常量,不可改变
StringBuilder和StringBuffer描述的字符串不是常量,可以发生改变
StringBuilder和StringBuffer的区别:
StringBuffer类是从jdk1.0开始存在,属于线程安全的类,因此效率比较低。
StringBuilder类是从jdk1.5开始存在,属于非线程安全的类,效率比较高。
基本概念
由于String类描述的字符串内容是个常量不可改变,当需要在Java代码中描述大量类似的字符串
时,只能单独申请和存储,此时会造成内存空间的浪费。
为了解决上述问题,可以使用java.lang.StringBuilder类和java.lang.StringBuffer类来描述字符序
列可以改变的字符串,如:"ab"。
注意:
现在还没有学到线程,所有首选StringBuilder因为它效率比较高;
StringBuilder类常用的构造方法
StringBuilder()的初始容量是16,就是使用无参方式new该对象时,它申请了一块内存空间这个空间可以存放16个字符。
package com.lagou.task13; public class StringBuilderTest { public static void main(String[] args) { // 使用无参方式打印StringBuider类型的容量和长度 StringBuilder sb1 = new StringBuilder(); System.out.println("sb1 = " + sb1); System.out.println("初始容量是:" + sb1.capacity()); System.out.println("长度是:" + sb1.length()); System.out.println("-------------------------------------"); // 使用有参方式打印StringBuider类型的容量和长度 StringBuilder sb2 = new StringBuilder(20); System.out.println("sb2 = " + sb2); System.out.println("初始容量是:" + sb2.capacity()); System.out.println("长度是:" + sb2.length()); System.out.println("-------------------------------------"); // 使用有参方式打印StringBuider类型的容量和长度 StringBuilder sb3 = new StringBuilder("hello"); System.out.println("sb3 = " + sb3); System.out.println("初始容量是:" + sb3.capacity()); System.out.println("长度是:" + sb3.length()); } }
StringBuilder类常用的成员方法
String类描述的是字符串不可改变的内容就是常量,无论调用什么方法该内容值都不会发生改变;StringBuilder类描述的字符串是可以发生改变的内容,无论是返回值还是调用对象本身都是返回自己所有该值发生改变;
package com.lagou.task13; public class StringBuilderTest { public static void main(String[] args) { // 使用无参方式打印StringBuider类型的容量和长度 StringBuilder sb1 = new StringBuilder(); System.out.println("sb1 = " + sb1); System.out.println("初始容量是:" + sb1.capacity()); System.out.println("长度是:" + sb1.length()); System.out.println("-------------------------------------"); // 使用有参方式打印StringBuider类型的容量和长度 StringBuilder sb2 = new StringBuilder(20); System.out.println("sb2 = " + sb2); System.out.println("初始容量是:" + sb2.capacity()); System.out.println("长度是:" + sb2.length()); System.out.println("-------------------------------------"); // 使用有参方式打印StringBuider类型的容量和长度 StringBuilder sb3 = new StringBuilder("hello"); System.out.println("sb3 = " + sb3); System.out.println("初始容量是:" + sb3.capacity()); System.out.println("长度是:" + sb3.length()); System.out.println("-------------------------------------"); // 4.实现向字符串中插入和追加字符串内容 // 向下标为0的位置插入字符串内容”abcd“,也就是向开头位置插入字符串内容 StringBuilder sb4 = sb3.insert(0,"abcd"); System.out.println("sb4 = " + sb4); System.out.println("sb3 = " + sb3); //insert方法返回调用对象自己,也就是返回值和调用对象是同一个字符串 System.out.println("-------------------------------------"); // 向中间位置插入字符串 sb4 = sb4.insert(4,"1234"); System.out.println("sb4 = " + sb4); // 向末尾位置插入字符串 sb4.append("ssssssssss"); //字符的个数超过初始容量时没有报错,我们可以发现它有一个自动的扩容机制 System.out.println("sb4 = " + sb4); // 当字符串的长度超过了字符串对象的初始容量时,该字符串对象会自动扩容,默认扩容算法是:原始容量*2 + 2 =》 21 * 2 + 2 =》44 // 底层使用byte【】 数组来存放该类的所有字符内容。 System.out.println("容量是: " + sb4.capacity()); System.out.println("长度是:" + sb4.length()); System.out.println("-------------------------------------"); // 5.实现字符串中字符和字符串的删除 // 注意:删除一个字符后会跳过一个字符继续删除,因为每当删除一个字符后后面的字符会向前补位,因此下标会发生改变 System.out.println("sb4 = "+ sb4); for (int i=0 ;i<3;i++){ sb4.deleteCharAt(0); } System.out.println("sb4 = "+ sb4); System.out.println("-------------------------------------"); // 删除起始字符串hello,包含0但不包含4 sb4.delete(5,10); System.out.println("sb4 = "+ sb4); System.out.println("-------------------------------------"); // 6.实现字符串内容的修改、查找以及反转操作 // 将下标为0位置的字符修改为a sb4.setCharAt(0,'a'); System.out.println("修改后的SB4:" + sb4); // 修改“1234”为bcde sb4.replace(1,5,"bcde"); System.out.println("修改后的SB4:" + sb4); // 实现查找功能 int pos = sb4.indexOf("a"); System.out.println("从前往后查找的结果是:" + pos); int pos1 = sb4.lastIndexOf("a"); System.out.println("从后往前查找的结果是:" + pos1); // 实现字符串反转 sb4.reverse(); System.out.println("反转后的结果是:" + sb4); } }
字符串类的笔试考点
// 7.笔试考点 // 考点一:既然StringBuilder类的对象本身可以修改,那么为什么成员方法还有返回值呢? // 其实我们刚刚调用完增删改操作以后当前代码的序列已经发生改变了,我们直接打印调用对象本身已经变了,但是我们打开源码以后我们可以发现这些代码的返回值都是StringBuilder类型,而且这个源码里面都是返回this; // 解析:为了连续调用 // sb4.reverse().append("1").append("2").insert(0,"3").delete(0,1).reverse(); // 如果没有返回值的话,我们写代码就不能连续调用,写代码的时候只能sb4.reverse() 空格 sb4.append("1") // 考点二:如何实现StringBuilder类型和String类型之间的转换? // String str4 = sb4.toString(); // StringBuilder sb5 = new StringBuilder(str4); // 考点三:String、StringBuilder、StringBuffer之间效率谁高?排列如何? // String<StringBuffer<StringBuilder