

- public class StringBuffer01 {
- public static void main(String[] args) {
- //老韩解读
- //1. StringBuffer 的直接父类 是 AbstractStringBuilder
- //2. StringBuffer 实现了 Serializable, 即StringBuffer的对象可以串行化
- //3. 在父类中 AbstractStringBuilder 有属性 char[] value,不是final
- // 该 value 数组存放 字符串内容,因此存放在堆中的
- //4. StringBuffer 是一个 final类,不能被继承
- //5. 因为StringBuffer 字符内容是存在 char[] value, 所有在变化(增加/删除)
- // 不用每次都更换地址(即不是每次创建新对象), 所以效率高于 String
-
- StringBuffer stringBuffer = new StringBuffer("hello");
- }
- }
String保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更改地址,效率较低//private final char value[l;
StringBuffer保存的是字符串变量,里面的值可以更改,每次StringBuffer的更新实际上可以更新内容,不用每次更新地址,效率较高//char[] value;这个放在堆.

- public class StringBuffer02 {
- public static void main(String[] args) {
-
- //构造器的使用
- //老韩解读
- //1. 创建一个 大小为 16的 char[] ,用于存放字符内容
- StringBuffer stringBuffer = new StringBuffer();
-
- //2 通过构造器指定 char[] 大小
- StringBuffer stringBuffer1 = new StringBuffer(100);
-
- //3. 通过 给一个String 创建 StringBuffer, char[] 大小就是 str.length() + 16
- StringBuffer hello = new StringBuffer("hello");
-
- }
- }
在开发中,我们经常需要将String 和StringBuffer进行转换,看看如何实现,
- public class StringAndStringBuffer {
- public static void main(String[] args) {
-
- //看 String——>StringBuffer
- String str = "hello tom";
- //方式1 使用构造器
- //注意: 返回的才是StringBuffer对象,对str 本身没有影响
- StringBuffer stringBuffer = new StringBuffer(str);
- //方式2 使用的是append方法
- StringBuffer stringBuffer1 = new StringBuffer();
- stringBuffer1 = stringBuffer1.append(str);
-
- //看看 StringBuffer ->String
- StringBuffer stringBuffer3 = new StringBuffer("韩顺平教育");
- //方式1 使用StringBuffer提供的 toString方法
- String s = stringBuffer3.toString();
- //方式2: 使用构造器来搞定
- String s1 = new String(stringBuffer3);
-
- }
- }

- public class StringBufferMethod {
- public static void main(String[] args) {
-
- StringBuffer s = new StringBuffer("hello");
- //增
- s.append(',');// "hello,"
- s.append("张三丰");//"hello,张三丰"
- s.append("赵敏").append(100).append(true).append(10.5);//"hello,张三丰赵敏100true10.5"
- System.out.println(s);//"hello,张三丰赵敏100true10.5"
-
-
- //删
- /*
- * 删除索引为>=start &&
- * 解读: 删除 11~14的字符 [11, 14)
- */
- s.delete(11, 14);
- System.out.println(s);//"hello,张三丰赵敏true10.5"
- //改
- //老韩解读,使用 周芷若 替换 索引9-11的字符 [9,11)
- s.replace(9, 11, "周芷若");
- System.out.println(s);//"hello,张三丰周芷若true10.5"
- //查找指定的子串在字符串第一次出现的索引,如果找不到返回-1
- int indexOf = s.indexOf("张三丰");
- System.out.println(indexOf);//6
- //插
- //老韩解读,在索引为9的位置插入 "赵敏",原来索引为9的内容自动后移
- s.insert(9, "赵敏");
- System.out.println(s);//"hello,张三丰赵敏周芷若true10.5"
- //长度
- System.out.println(s.length());//22
- System.out.println(s);
-
- }
- }
- public class StringBufferExercise01 {
- public static void main(String[] args) {
- String str = null;// ok
- StringBuffer sb = new StringBuffer(); //ok
- sb.append(str);//需要看源码 , 底层调用的是 AbstractStringBuilder 的 appendNull
- System.out.println(sb.length());//4
-
- System.out.println(sb);//null
- //下面的构造器,会抛出NullpointerException
- StringBuffer sb1 = new StringBuffer(str);//看底层源码 super(str.length() + 16);
- System.out.println(sb1);
-
- }
- }


练习2
- 输入商品名称和商品价格,要求打印效果示例, 使用前面学习的方法完成:
- 商品名 商品价格
- 手机 123,564.59 //比如 价格 3,456,789.88
-
- 要求:价格的小数点前面每三位用逗号隔开, 再输出。
-
- 思路分析
- 1. 定义一个Scanner 对象,接收用户输入的 价格(String)
- 2. 希望使用到 StringBuffer的 insert ,需要将 String 转成 StringBuffer
- 3. 然后使用相关方法进行字符串的处理
- public class StringBufferExercise02 {
- public static void main(String[] args) {
- /*
- 输入商品名称和商品价格,要求打印效果示例, 使用前面学习的方法完成:
- 商品名 商品价格
- 手机 123,564.59 //比如 价格 3,456,789.88
- 要求:价格的小数点前面每三位用逗号隔开, 在输出。
- 思路分析
- 1. 定义一个Scanner 对象,接收用户输入的 价格(String)
- 2. 希望使用到 StringBuffer的 insert ,需要将 String 转成 StringBuffer
- 3. 然后使用相关方法进行字符串的处理
- 代码实现
- */
-
- //new Scanner(System.in)
- String price = "8123564.59";
- StringBuffer sb = new StringBuffer(price);
- //先完成一个最简单的实现123,564.59
- //找到小数点的索引,然后在该位置的前3位,插入,即可
- // int i = sb.lastIndexOf(".");
- // sb = sb.insert(i - 3, ",");
-
- //上面的两步需要做一个循环处理,才是正确的
- for (int i = sb.lastIndexOf(".") - 3; i > 0; i -= 3) {
- sb = sb.insert(i, ",");
- }
- System.out.println(sb);//8,123,564.59
-
-
- }
- }
1)一个可变的字符序列。此类提供一个与StringBuffer兼容的API,但不保证同步(StringBuilder不是线程安全)。该类被设计用作 StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候。如果可能,建议优先采用该类.因为在大多数实现中,它比 StringBuffer要快[后面测]】。
2)在 StringBuilder 上的主要操作是append和 insert方法,可重载这些方法,以接受任意类型的数据。

- public class StringBuilder01 {
- public static void main(String[] args) {
- //老韩解读
- //1. StringBuilder 继承 AbstractStringBuilder 类
- //2. 实现了 Serializable ,说明StringBuilder对象是可以串行化(对象可以网络传输,可以保存到文件)
- //3. StringBuilder 是final类, 不能被继承
- //4. StringBuilder 对象字符序列仍然是存放在其父类 AbstractStringBuilder的 char[] value;
- // 因此,字符序列是堆中
- //5. StringBuilder 的方法,没有做互斥的处理,即没有synchronized 关键字,因此在单线程的情况下使用
- // StringBuilder
- StringBuilder stringBuilder = new StringBuilder();
- }
- }
StringBuilder和 StringBuffer非常类似,均代表可变的字符序列,而且方法也一样
String:不可变字符序列,效率低,但是复用率高。
StringBuffer:可变字符序列、效率较高(增删)、线程安全,看源码
StringBuilder:可变字符序列、效率最高、线程不安全
String使用注意说明:
string s="a";//创建了一个字符串
s += "b";//实际上原来的"a"字符串对象已经丢弃了,现在又产生了一个字符串s+"b”(也就是"ab")。如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大影响程序的性能=>结论:如果我们对String做大量修改,不要使用String
StringBuilder > StringBuffer > String

- public class StringVsStringBufferVsStringBuilder {
- public static void main(String[] args) {
-
- long startTime = 0L;
- long endTime = 0L;
- StringBuffer buffer = new StringBuffer("");
-
- startTime = System.currentTimeMillis();
- for (int i = 0; i < 80000; i++) {//StringBuffer 拼接 20000次
- buffer.append(String.valueOf(i));
- }
- endTime = System.currentTimeMillis();
- System.out.println("StringBuffer的执行时间:" + (endTime - startTime));
-
-
-
-
-
- StringBuilder builder = new StringBuilder("");
- startTime = System.currentTimeMillis();
- for (int i = 0; i < 80000; i++) {//StringBuilder 拼接 20000次
- builder.append(String.valueOf(i));
- }
- endTime = System.currentTimeMillis();
- System.out.println("StringBuilder的执行时间:" + (endTime - startTime));
-
-
- String text = "";
- startTime = System.currentTimeMillis();
- for (int i = 0; i < 80000; i++) {//String 拼接 20000
- text = text + i;
- }
- endTime = System.currentTimeMillis();
- System.out.println("String的执行时间:" + (endTime - startTime));
-
- }
- }
使用的原则,结论:
1.如果字符串存在大量的修改操作,一般使用StringBuffer 或StringBuilder;
2.如果字符串存在大量的修改操作,并在单线程的情况,使用 StringBuilder;
3.如果字符串存在大量的修改操作,并在多线程的情况,使用 StringBuffer;
4.如果我们字符串很少修改,被多个对象引用,使用String, 比如配置信息等
StringBuilder的方法使用和 StringBuffer 一样,不再说